cnss2: Sync code from kernel 4.14
Sync cnss2 codes to kernel 4.9 from kernel 4.14 for qca6595 and qca6696. The code from 4.14 is based on the commit:a9567eae9d979dcf83e73ef4e31d4ecbdb553e70 in msm-4.14. Because the APIs of qmi are not updated with 4.14, so keep these qmi interfaces. Add the description of cnss-qca-converged in cnss-wlan.txt. CRs-Fixed: 2685017 Change-Id: I88a6d3a7dd4bd8209cd7aa83336b48fc1f0371e0 Signed-off-by: Kuichu Ni <kuichun@codeaurora.org>
This commit is contained in:
parent
d49d3b2f97
commit
63adfad31b
19 changed files with 3491 additions and 564 deletions
|
|
@ -14,6 +14,7 @@ Required properties:
|
|||
- compatible: "qcom,cnss" for QCA6174 device
|
||||
"qcom,cnss-qca6290" for QCA6290 device
|
||||
"qcom,cnss-qca6390" for QCA6390 device
|
||||
"qcom,cnss-qca-converged" for converged QCA devices
|
||||
- wlan-en-gpio: WLAN_EN GPIO signal specified by the chip specifications
|
||||
- vdd-wlan-supply: phandle to the regulator device tree node
|
||||
- pinctrl-names: Names corresponding to the numbered pinctrl states
|
||||
|
|
@ -35,6 +36,10 @@ Optional properties:
|
|||
- vdd-wlan-xtal-aon-supply: phandle to the LDO-4 regulator. This is needed
|
||||
on platforms where XTAL regulator depends on
|
||||
always on regulator in VDDmin.
|
||||
- vdd-wlan-ctrl1-supply: phandle to the DBU1 - 1.8V for QCA6595 or 3.3V for
|
||||
QCA6174 on auto platform.
|
||||
- vdd-wlan-ctrl2-supply: phandle to the DBU4 - 2.2V for QCA6595 or 3.85V for
|
||||
QCA6696 on auto platform.
|
||||
- vdd-wlan-core-supply: phandle to the 1.3V CORE regulator for QCA6174
|
||||
- vdd-wlan-sp2t-supply: phandle to the 2.7V SP2T regulator for QCA6174
|
||||
- qcom,smmu-s1-enable: Boolean property to decide whether to enable SMMU
|
||||
|
|
@ -56,7 +61,32 @@ Optional properties:
|
|||
WLAN_EN pin is a gpio or fixed regulator.
|
||||
- qcom,mhi: phandle to indicate the device which needs MHI support.
|
||||
- qcom,cap-tsf-gpio: WLAN_TSF_CAPTURED GPIO signal specified by the chip
|
||||
specifications, should be drived depending on products
|
||||
specifications, should be drived depending on products.
|
||||
- cnss-daemon-support: Boolean property to decide whether cnss_daemon
|
||||
userspace QMI client is supported.
|
||||
- qcom,converged-dt: Boolean property to decide whether it supports multiple
|
||||
chips.
|
||||
- qcom,bus-type: U32 property to specify the bus type, is required when
|
||||
'qcom,converged-dt' being present.
|
||||
- wlan_vregs: String array to decide which vregs are required, is required
|
||||
when 'qcom,converged-dt' being present.
|
||||
- <supply-name>-supply: phandle to the regulator device tree node.
|
||||
optional "supply-name" is "vdd-wlan-rfa".
|
||||
- qcom,<supply-name>-info: Specifies configuration for supply. Should be
|
||||
specified in <min_uV max_uV load_uA delay_us>.
|
||||
- pcie-disable-l1: Boolean property to decide whether to disable PCIe L1 PM.
|
||||
- pcie-disable-l1ss: Boolean property to decide whether to disable PCIe L1ss.
|
||||
- qcom,set-wlaon-pwr-ctrl: Boolean property to indicate if set
|
||||
WLAON_QFPROM_PWR_CTRL_REG register during power on
|
||||
and off sequences.
|
||||
|
||||
List of chip specific sub nodes:
|
||||
- chip_cfg@X: represent chip specific configurations
|
||||
Each sub node has the following required properties:
|
||||
- wlan_vregs: String array to decide which vregs are required, property
|
||||
being present but no values means no additional vregs.
|
||||
- supported-ids: U32 array to decide which device ids are supported by
|
||||
sub node.
|
||||
|
||||
Example:
|
||||
|
||||
|
|
@ -76,3 +106,27 @@ Example:
|
|||
qcom,mhi = <&mhi_wlan>;
|
||||
qcom,cap-tsf-gpio = <&tlmm 126 1>;
|
||||
};
|
||||
|
||||
qcom,cnss-qca-converged {
|
||||
compatible = "qcom,cnss-qca-converged";
|
||||
qcom,converged-dt;
|
||||
qcom,bus-type=<0>;
|
||||
|
||||
vdd-wlan-ctrl1-supply = <&vreg_conn_pa>;
|
||||
vdd-wlan-ctrl2-supply = <&vreg_conn_1p8>;
|
||||
vdd-wlan-supply = <&vreg_wlan>;
|
||||
wlan_vregs = "vdd-wlan-ctrl1", "vdd-wlan-ctrl2";
|
||||
qcom,vdd-wlan-ctrl1-info = <0 0 0 0>;
|
||||
qcom,vdd-wlan-ctrl2-info = <0 0 0 0>;
|
||||
wlan-en-gpio = <&tlmm 169 0>;
|
||||
pinctrl-names = "wlan_en_active", "wlan_en_sleep";
|
||||
pinctrl-0 = <&cnss_wlan_en_active>;
|
||||
pinctrl-1 = <&cnss_wlan_en_sleep>;
|
||||
qcom,wlan-rc-num = <0>;
|
||||
|
||||
chip_cfg@1 {
|
||||
supported-ids = <0x003e>;
|
||||
wlan_vregs = "vdd-wlan";
|
||||
qcom,vdd-wlan-info = <0 0 0 10>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ cnss2-y += debug.o
|
|||
cnss2-y += pci.o
|
||||
cnss2-y += usb.o
|
||||
cnss2-y += power.o
|
||||
cnss2-$(CONFIG_CNSS2_DEBUG) += genl.o
|
||||
cnss2-$(CONFIG_CNSS2_QMI) += qmi.o wlan_firmware_service_v01.o
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2018-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -29,40 +29,52 @@ enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev)
|
|||
return CNSS_BUS_NONE;
|
||||
}
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id)
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
switch (device_id) {
|
||||
int ret;
|
||||
struct device *dev;
|
||||
u32 bus_type = CNSS_BUS_NONE;
|
||||
|
||||
if (plat_priv->is_converged_dt) {
|
||||
dev = &plat_priv->plat_dev->dev;
|
||||
ret = of_property_read_u32(dev->of_node, "qcom,bus-type",
|
||||
&bus_type);
|
||||
if (!ret)
|
||||
cnss_pr_dbg("Got bus type[%u] from dt\n", bus_type);
|
||||
else
|
||||
cnss_pr_err("No bus type for converged dt\n");
|
||||
|
||||
return bus_type;
|
||||
}
|
||||
|
||||
/* Get bus type according to device id if it's not converged DT */
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
return CNSS_BUS_PCI;
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
bus_type = CNSS_BUS_PCI;
|
||||
break;
|
||||
case QCN7605_COMPOSITE_DEVICE_ID:
|
||||
case QCN7605_STANDALONE_DEVICE_ID:
|
||||
return CNSS_BUS_USB;
|
||||
bus_type = CNSS_BUS_USB;
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Unknown device_id: 0x%lx\n", device_id);
|
||||
return CNSS_BUS_NONE;
|
||||
cnss_pr_err("Unknown device: 0x%lx\n", plat_priv->device_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return bus_type;
|
||||
}
|
||||
|
||||
bool cnss_bus_req_mem_ind_valid(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (cnss_get_bus_type(plat_priv->device_id) == CNSS_BUS_USB)
|
||||
if (cnss_get_bus_type(plat_priv) == CNSS_BUS_USB)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cnss_bus_dev_cal_rep_valid(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if (cnss_get_bus_type(plat_priv->device_id) == CNSS_BUS_USB)
|
||||
ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev)
|
||||
{
|
||||
if (!dev)
|
||||
|
|
@ -161,6 +173,37 @@ int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv)
|
|||
}
|
||||
}
|
||||
|
||||
int cnss_bus_alloc_qdss_mem(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
return cnss_pci_alloc_qdss_mem(plat_priv->bus_priv);
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void cnss_bus_free_qdss_mem(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
return;
|
||||
|
||||
switch (plat_priv->bus_type) {
|
||||
case CNSS_BUS_PCI:
|
||||
cnss_pci_free_qdss_mem(plat_priv->bus_priv);
|
||||
return;
|
||||
default:
|
||||
cnss_pr_err("Unsupported bus type: %d\n",
|
||||
plat_priv->bus_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (!plat_priv)
|
||||
|
|
@ -388,3 +431,18 @@ int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
|
|||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
int cnss_get_msi_assignment(struct cnss_plat_data *plat_priv,
|
||||
char *msi_name,
|
||||
int *num_vectors, u32 *user_base_data,
|
||||
u32 *base_vector)
|
||||
{
|
||||
struct cnss_pci_data *pci_priv;
|
||||
|
||||
pci_priv = plat_priv->bus_priv;
|
||||
return cnss_get_user_msi_assignment(&pci_priv->pci_dev->dev,
|
||||
msi_name,
|
||||
num_vectors,
|
||||
user_base_data,
|
||||
base_vector);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2018-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -22,27 +22,28 @@
|
|||
#define QCA6174_REV3_2_VERSION 0x5030000
|
||||
#define QCA6290_VENDOR_ID 0x17CB
|
||||
#define QCA6290_DEVICE_ID 0x1100
|
||||
#define QCA6290_EMULATION_VENDOR_ID 0x168C
|
||||
#define QCA6290_EMULATION_DEVICE_ID 0xABCD
|
||||
#define QCA6390_VENDOR_ID 0x17CB
|
||||
#define QCA6390_EMULATION_DEVICE_ID 0x0108
|
||||
#define QCA6390_DEVICE_ID 0x1101
|
||||
#define QCN7605_VENDOR_ID 0x17CB
|
||||
#define QCN7605_DEVICE_ID 0x1102
|
||||
|
||||
#define QCN7605_USB_VENDOR_ID 0x05C6
|
||||
#define QCN7605_COMPOSITE_DEVICE_ID QCN7605_COMPOSITE_PRODUCT_ID
|
||||
#define QCN7605_STANDALONE_DEVICE_ID QCN7605_STANDALONE_PRODUCT_ID
|
||||
|
||||
#define QCN7605_STANDALONE_PRODUCT_ID 0x9900
|
||||
#define QCN7605_COMPOSITE_PRODUCT_ID 0x9901
|
||||
|
||||
#define QCN7605_COMPOSITE_DEVICE_ID QCN7605_COMPOSITE_PRODUCT_ID
|
||||
#define QCN7605_STANDALONE_DEVICE_ID QCN7605_STANDALONE_PRODUCT_ID
|
||||
|
||||
enum cnss_dev_bus_type cnss_get_dev_bus_type(struct device *dev);
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(unsigned long device_id);
|
||||
enum cnss_dev_bus_type cnss_get_bus_type(struct cnss_plat_data *plat_priv);
|
||||
void *cnss_bus_dev_to_bus_priv(struct device *dev);
|
||||
struct cnss_plat_data *cnss_bus_dev_to_plat_priv(struct device *dev);
|
||||
int cnss_bus_init(struct cnss_plat_data *plat_priv);
|
||||
void cnss_bus_deinit(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_load_m3(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_alloc_fw_mem(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_alloc_qdss_mem(struct cnss_plat_data *plat_priv);
|
||||
void cnss_bus_free_qdss_mem(struct cnss_plat_data *plat_priv);
|
||||
u32 cnss_bus_get_wake_irq(struct cnss_plat_data *plat_priv);
|
||||
int cnss_bus_force_fw_assert_hdlr(struct cnss_plat_data *plat_priv);
|
||||
void cnss_bus_fw_boot_timeout_hdlr(unsigned long data);
|
||||
|
|
@ -60,8 +61,10 @@ int cnss_bus_call_driver_modem_status(struct cnss_plat_data *plat_priv,
|
|||
int modem_current_status);
|
||||
int cnss_bus_update_status(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_driver_status status);
|
||||
int cnss_bus_recovery_update_status(struct cnss_plat_data *plat_priv);
|
||||
bool cnss_bus_req_mem_ind_valid(struct cnss_plat_data *plat_priv);
|
||||
bool cnss_bus_dev_cal_rep_valid(struct cnss_plat_data *plat_priv);
|
||||
|
||||
int cnss_get_msi_assignment(struct cnss_plat_data *plat_priv,
|
||||
char *msi_name,
|
||||
int *num_vectors,
|
||||
u32 *user_base_data,
|
||||
u32 *base_vector);
|
||||
#endif /* _CNSS_BUS_H */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -85,6 +85,12 @@ static int cnss_stats_show_state(struct seq_file *s,
|
|||
case CNSS_DRIVER_UNLOADING:
|
||||
seq_puts(s, "DRIVER_UNLOADING");
|
||||
continue;
|
||||
case CNSS_DRIVER_IDLE_RESTART:
|
||||
seq_puts(s, "IDLE_RESTART");
|
||||
continue;
|
||||
case CNSS_DRIVER_IDLE_SHUTDOWN:
|
||||
seq_puts(s, "IDLE_SHUTDOWN");
|
||||
continue;
|
||||
case CNSS_DRIVER_PROBED:
|
||||
seq_puts(s, "DRIVER_PROBED");
|
||||
continue;
|
||||
|
|
@ -100,6 +106,9 @@ static int cnss_stats_show_state(struct seq_file *s,
|
|||
case CNSS_DRIVER_DEBUG:
|
||||
seq_puts(s, "DRIVER_DEBUG");
|
||||
continue;
|
||||
case CNSS_IN_SUSPEND_RESUME:
|
||||
seq_puts(s, "IN_SUSPEND_RESUME");
|
||||
continue;
|
||||
}
|
||||
|
||||
seq_printf(s, "UNKNOWN-%d", i);
|
||||
|
|
@ -504,6 +513,145 @@ static const struct file_operations cnss_runtime_pm_debug_fops = {
|
|||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
static ssize_t cnss_control_params_debug_write(struct file *fp,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *off)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv =
|
||||
((struct seq_file *)fp->private_data)->private;
|
||||
char buf[64];
|
||||
char *sptr, *token;
|
||||
char *cmd;
|
||||
u32 val;
|
||||
unsigned int len = 0;
|
||||
const char *delim = " ";
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
sptr = buf;
|
||||
|
||||
token = strsep(&sptr, delim);
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (!sptr)
|
||||
return -EINVAL;
|
||||
cmd = token;
|
||||
|
||||
token = strsep(&sptr, delim);
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou32(token, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (strcmp(cmd, "quirks") == 0)
|
||||
plat_priv->ctrl_params.quirks = val;
|
||||
else if (strcmp(cmd, "mhi_timeout") == 0)
|
||||
plat_priv->ctrl_params.mhi_timeout = val;
|
||||
else if (strcmp(cmd, "qmi_timeout") == 0)
|
||||
plat_priv->ctrl_params.qmi_timeout = val;
|
||||
else if (strcmp(cmd, "bdf_type") == 0)
|
||||
plat_priv->ctrl_params.bdf_type = val;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int cnss_show_quirks_state(struct seq_file *s,
|
||||
struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
enum cnss_debug_quirks i;
|
||||
int skip = 0;
|
||||
unsigned long state;
|
||||
|
||||
seq_printf(s, "quirks: 0x%lx (", plat_priv->ctrl_params.quirks);
|
||||
for (i = 0, state = plat_priv->ctrl_params.quirks;
|
||||
state != 0; state >>= 1, i++) {
|
||||
if (!(state & 0x1))
|
||||
continue;
|
||||
if (skip++)
|
||||
seq_puts(s, " | ");
|
||||
|
||||
switch (i) {
|
||||
case LINK_DOWN_SELF_RECOVERY:
|
||||
seq_puts(s, "LINK_DOWN_SELF_RECOVERY");
|
||||
continue;
|
||||
case SKIP_DEVICE_BOOT:
|
||||
seq_puts(s, "SKIP_DEVICE_BOOT");
|
||||
continue;
|
||||
case USE_CORE_ONLY_FW:
|
||||
seq_puts(s, "USE_CORE_ONLY_FW");
|
||||
continue;
|
||||
case SKIP_RECOVERY:
|
||||
seq_puts(s, "SKIP_RECOVERY");
|
||||
continue;
|
||||
case QMI_BYPASS:
|
||||
seq_puts(s, "QMI_BYPASS");
|
||||
continue;
|
||||
case ENABLE_WALTEST:
|
||||
seq_puts(s, "WALTEST");
|
||||
continue;
|
||||
case ENABLE_PCI_LINK_DOWN_PANIC:
|
||||
seq_puts(s, "PCI_LINK_DOWN_PANIC");
|
||||
continue;
|
||||
case FBC_BYPASS:
|
||||
seq_puts(s, "FBC_BYPASS");
|
||||
continue;
|
||||
case ENABLE_DAEMON_SUPPORT:
|
||||
seq_puts(s, "DAEMON_SUPPORT");
|
||||
continue;
|
||||
case IGNORE_PCI_LINK_FAILURE:
|
||||
seq_puts(s, "IGNORE_PCI_LINK_FAILURE");
|
||||
continue;
|
||||
}
|
||||
|
||||
seq_printf(s, "UNKNOWN-%d", i);
|
||||
}
|
||||
seq_puts(s, ")\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_control_params_debug_show(struct seq_file *s, void *data)
|
||||
{
|
||||
struct cnss_plat_data *cnss_priv = s->private;
|
||||
|
||||
seq_puts(s, "\nUsage: echo <params_name> <value> > <debugfs_path>/cnss/control_params\n");
|
||||
seq_puts(s, "<params_name> can be one of below:\n");
|
||||
seq_puts(s, "quirks: Debug quirks for driver\n");
|
||||
seq_puts(s, "mhi_timeout: Timeout for MHI operation in milliseconds\n");
|
||||
seq_puts(s, "qmi_timeout: Timeout for QMI message in milliseconds\n");
|
||||
seq_puts(s, "bdf_type: Type of board data file to be downloaded\n");
|
||||
|
||||
seq_puts(s, "\nCurrent value:\n");
|
||||
cnss_show_quirks_state(s, cnss_priv);
|
||||
seq_printf(s, "mhi_timeout: %u\n", cnss_priv->ctrl_params.mhi_timeout);
|
||||
seq_printf(s, "qmi_timeout: %u\n", cnss_priv->ctrl_params.qmi_timeout);
|
||||
seq_printf(s, "bdf_type: %u\n", cnss_priv->ctrl_params.bdf_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_control_params_debug_open(struct inode *inode,
|
||||
struct file *file)
|
||||
{
|
||||
return single_open(file, cnss_control_params_debug_show,
|
||||
inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations cnss_control_params_debug_fops = {
|
||||
.read = seq_read,
|
||||
.write = cnss_control_params_debug_write,
|
||||
.open = cnss_control_params_debug_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = seq_lseek,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
|
|
@ -517,6 +665,8 @@ static int cnss_create_debug_only_node(struct cnss_plat_data *plat_priv)
|
|||
&cnss_reg_write_debug_fops);
|
||||
debugfs_create_file("runtime_pm", 0600, root_dentry, plat_priv,
|
||||
&cnss_runtime_pm_debug_fops);
|
||||
debugfs_create_file("control_params", 0600, root_dentry, plat_priv,
|
||||
&cnss_control_params_debug_fops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -63,6 +63,9 @@ extern void *cnss_ipc_log_context;
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
#define cnss_fatal_err(_fmt, ...) \
|
||||
cnss_pr_err("fatal: " _fmt, ##__VA_ARGS__)
|
||||
|
||||
int cnss_debug_init(void);
|
||||
void cnss_debug_deinit(void);
|
||||
int cnss_debugfs_create(struct cnss_plat_data *plat_priv);
|
||||
|
|
|
|||
213
drivers/net/wireless/cnss2/genl.c
Normal file
213
drivers/net/wireless/cnss2/genl.c
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/* Copyright (c) 2019-2020, The Linux Foundation. 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 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the 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.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "cnss_genl: " fmt
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "debug.h"
|
||||
#include "genl.h"
|
||||
|
||||
#define CNSS_GENL_FAMILY_NAME "cnss-genl"
|
||||
#define CNSS_GENL_MCAST_GROUP_NAME "cnss-genl-grp"
|
||||
#define CNSS_GENL_VERSION 1
|
||||
#define CNSS_GENL_DATA_LEN_MAX (15 * 1024)
|
||||
#define CNSS_GENL_STR_LEN_MAX 16
|
||||
|
||||
enum {
|
||||
CNSS_GENL_ATTR_MSG_UNSPEC,
|
||||
CNSS_GENL_ATTR_MSG_TYPE,
|
||||
CNSS_GENL_ATTR_MSG_FILE_NAME,
|
||||
CNSS_GENL_ATTR_MSG_TOTAL_SIZE,
|
||||
CNSS_GENL_ATTR_MSG_SEG_ID,
|
||||
CNSS_GENL_ATTR_MSG_END,
|
||||
CNSS_GENL_ATTR_MSG_DATA_LEN,
|
||||
CNSS_GENL_ATTR_MSG_DATA,
|
||||
__CNSS_GENL_ATTR_MAX,
|
||||
};
|
||||
|
||||
#define CNSS_GENL_ATTR_MAX (__CNSS_GENL_ATTR_MAX - 1)
|
||||
|
||||
enum {
|
||||
CNSS_GENL_CMD_UNSPEC,
|
||||
CNSS_GENL_CMD_MSG,
|
||||
__CNSS_GENL_CMD_MAX,
|
||||
};
|
||||
|
||||
#define CNSS_GENL_CMD_MAX (__CNSS_GENL_CMD_MAX - 1)
|
||||
|
||||
static struct nla_policy cnss_genl_msg_policy[CNSS_GENL_ATTR_MAX + 1] = {
|
||||
[CNSS_GENL_ATTR_MSG_TYPE] = { .type = NLA_U8 },
|
||||
[CNSS_GENL_ATTR_MSG_FILE_NAME] = { .type = NLA_NUL_STRING,
|
||||
.len = CNSS_GENL_STR_LEN_MAX },
|
||||
[CNSS_GENL_ATTR_MSG_TOTAL_SIZE] = { .type = NLA_U32 },
|
||||
[CNSS_GENL_ATTR_MSG_SEG_ID] = { .type = NLA_U32 },
|
||||
[CNSS_GENL_ATTR_MSG_END] = { .type = NLA_U8 },
|
||||
[CNSS_GENL_ATTR_MSG_DATA_LEN] = { .type = NLA_U32 },
|
||||
[CNSS_GENL_ATTR_MSG_DATA] = { .type = NLA_BINARY,
|
||||
.len = CNSS_GENL_DATA_LEN_MAX },
|
||||
};
|
||||
|
||||
static int cnss_genl_process_msg(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct genl_ops cnss_genl_ops[] = {
|
||||
{
|
||||
.cmd = CNSS_GENL_CMD_MSG,
|
||||
.policy = cnss_genl_msg_policy,
|
||||
.doit = cnss_genl_process_msg,
|
||||
},
|
||||
};
|
||||
|
||||
static struct genl_multicast_group cnss_genl_mcast_grp[] = {
|
||||
{
|
||||
.name = CNSS_GENL_MCAST_GROUP_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static struct genl_family cnss_genl_family = {
|
||||
.id = 0,
|
||||
.hdrsize = 0,
|
||||
.name = CNSS_GENL_FAMILY_NAME,
|
||||
.version = CNSS_GENL_VERSION,
|
||||
.maxattr = CNSS_GENL_ATTR_MAX,
|
||||
.module = THIS_MODULE,
|
||||
.ops = cnss_genl_ops,
|
||||
.n_ops = ARRAY_SIZE(cnss_genl_ops),
|
||||
.mcgrps = cnss_genl_mcast_grp,
|
||||
.n_mcgrps = ARRAY_SIZE(cnss_genl_mcast_grp),
|
||||
};
|
||||
|
||||
static int cnss_genl_send_data(u8 type, char *file_name, u32 total_size,
|
||||
u32 seg_id, u8 end, u32 data_len, u8 *msg_buff)
|
||||
{
|
||||
struct sk_buff *skb = NULL;
|
||||
void *msg_header = NULL;
|
||||
int ret = 0;
|
||||
char filename[CNSS_GENL_STR_LEN_MAX + 1];
|
||||
|
||||
cnss_pr_dbg("type: %u, file_name %s, total_size: %x, seg_id %u, end %u, data_len %u\n",
|
||||
type, file_name, total_size, seg_id, end, data_len);
|
||||
|
||||
if (!file_name)
|
||||
strlcpy(filename, "default", sizeof(filename));
|
||||
else
|
||||
strlcpy(filename, file_name, sizeof(filename));
|
||||
|
||||
skb = genlmsg_new(NLMSG_HDRLEN +
|
||||
nla_total_size(sizeof(type)) +
|
||||
nla_total_size(strlen(filename) + 1) +
|
||||
nla_total_size(sizeof(total_size)) +
|
||||
nla_total_size(sizeof(seg_id)) +
|
||||
nla_total_size(sizeof(end)) +
|
||||
nla_total_size(sizeof(data_len)) +
|
||||
nla_total_size(data_len), GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
msg_header = genlmsg_put(skb, 0, 0,
|
||||
&cnss_genl_family, 0,
|
||||
CNSS_GENL_CMD_MSG);
|
||||
if (!msg_header) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = nla_put_u8(skb, CNSS_GENL_ATTR_MSG_TYPE, type);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
ret = nla_put_string(skb, CNSS_GENL_ATTR_MSG_FILE_NAME, filename);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
ret = nla_put_u32(skb, CNSS_GENL_ATTR_MSG_TOTAL_SIZE, total_size);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
ret = nla_put_u32(skb, CNSS_GENL_ATTR_MSG_SEG_ID, seg_id);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
ret = nla_put_u8(skb, CNSS_GENL_ATTR_MSG_END, end);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
ret = nla_put_u32(skb, CNSS_GENL_ATTR_MSG_DATA_LEN, data_len);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
ret = nla_put(skb, CNSS_GENL_ATTR_MSG_DATA, data_len, msg_buff);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
genlmsg_end(skb, msg_header);
|
||||
ret = genlmsg_multicast(&cnss_genl_family, skb, 0, 0, GFP_KERNEL);
|
||||
if (ret < 0)
|
||||
cnss_pr_err("Fail to send genl msg: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
fail:
|
||||
cnss_pr_err("Fail to generate genl msg: %d\n", ret);
|
||||
if (skb)
|
||||
nlmsg_free(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_genl_send_msg(void *buff, u8 type, char *file_name, u32 total_size)
|
||||
{
|
||||
int ret = 0;
|
||||
u8 *msg_buff = buff;
|
||||
u32 remaining = total_size;
|
||||
u32 seg_id = 0;
|
||||
u32 data_len = 0;
|
||||
u8 end = 0;
|
||||
|
||||
cnss_pr_dbg("type: %u, total_size: %x\n", type, total_size);
|
||||
|
||||
while (remaining) {
|
||||
if (remaining > CNSS_GENL_DATA_LEN_MAX) {
|
||||
data_len = CNSS_GENL_DATA_LEN_MAX;
|
||||
} else {
|
||||
data_len = remaining;
|
||||
end = 1;
|
||||
}
|
||||
ret = cnss_genl_send_data(type, file_name, total_size,
|
||||
seg_id, end, data_len, msg_buff);
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("fail to send genl data, ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
remaining -= data_len;
|
||||
msg_buff += data_len;
|
||||
seg_id++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_genl_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = genl_register_family(&cnss_genl_family);
|
||||
if (ret != 0)
|
||||
cnss_pr_err("genl_register_family fail: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void cnss_genl_exit(void)
|
||||
{
|
||||
genl_unregister_family(&cnss_genl_family);
|
||||
}
|
||||
43
drivers/net/wireless/cnss2/genl.h
Normal file
43
drivers/net/wireless/cnss2/genl.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* Copyright (c) 2019-2020, The Linux Foundation. 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 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the 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 __CNSS_GENL_H__
|
||||
#define __CNSS_GENL_H__
|
||||
|
||||
enum cnss_genl_msg_type {
|
||||
CNSS_GENL_MSG_TYPE_UNSPEC,
|
||||
CNSS_GENL_MSG_TYPE_QDSS,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
int cnss_genl_init(void);
|
||||
void cnss_genl_exit(void);
|
||||
int cnss_genl_send_msg(void *buff, u8 type,
|
||||
char *file_name, u32 total_size);
|
||||
#else
|
||||
static inline int cnss_genl_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void cnss_genl_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int cnss_genl_send_msg(void *buff, u8 type,
|
||||
char *file_name, u32 total_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include "main.h"
|
||||
#include "bus.h"
|
||||
#include "debug.h"
|
||||
#include "genl.h"
|
||||
|
||||
#define CNSS_DUMP_FORMAT_VER 0x11
|
||||
#define CNSS_DUMP_FORMAT_VER_V2 0x22
|
||||
|
|
@ -38,28 +39,18 @@
|
|||
#define FW_ASSERT_TIMEOUT 5000
|
||||
#define CNSS_EVENT_PENDING 2989
|
||||
|
||||
#ifdef CONFIG_CNSS_EMULATION
|
||||
#define CNSS_MHI_TIMEOUT_DEFAULT 90000
|
||||
#else
|
||||
#define CNSS_MHI_TIMEOUT_DEFAULT 0
|
||||
#endif
|
||||
#define CNSS_QMI_TIMEOUT_DEFAULT 10000
|
||||
#define CNSS_BDF_TYPE_DEFAULT CNSS_BDF_ELF
|
||||
|
||||
static struct cnss_plat_data *plat_env;
|
||||
|
||||
static DECLARE_RWSEM(cnss_pm_sem);
|
||||
|
||||
static bool qmi_bypass;
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
module_param(qmi_bypass, bool, 0600);
|
||||
MODULE_PARM_DESC(qmi_bypass, "Bypass QMI from platform driver");
|
||||
#endif
|
||||
|
||||
static bool enable_waltest;
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
module_param(enable_waltest, bool, 0600);
|
||||
MODULE_PARM_DESC(enable_waltest, "Enable to handle firmware waltest");
|
||||
#endif
|
||||
|
||||
unsigned long quirks;
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
module_param(quirks, ulong, 0600);
|
||||
MODULE_PARM_DESC(quirks, "Debug quirks for the driver");
|
||||
#endif
|
||||
|
||||
static struct cnss_fw_files FW_FILES_QCA6174_FW_3_0 = {
|
||||
"qwlan30.bin", "bdwlan30.bin", "otp30.bin", "utf30.bin",
|
||||
"utfbd30.bin", "epping30.bin", "evicted30.bin"
|
||||
|
|
@ -185,9 +176,11 @@ int cnss_request_bus_bandwidth(struct device *dev, int bandwidth)
|
|||
|
||||
switch (bandwidth) {
|
||||
case CNSS_BUS_WIDTH_NONE:
|
||||
case CNSS_BUS_WIDTH_IDLE:
|
||||
case CNSS_BUS_WIDTH_LOW:
|
||||
case CNSS_BUS_WIDTH_MEDIUM:
|
||||
case CNSS_BUS_WIDTH_HIGH:
|
||||
case CNSS_BUS_WIDTH_VERY_HIGH:
|
||||
ret = msm_bus_scale_client_update_request(
|
||||
bus_bw_info->bus_client, bandwidth);
|
||||
if (!ret)
|
||||
|
|
@ -252,10 +245,13 @@ int cnss_wlan_enable(struct device *dev,
|
|||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (plat_priv->device_id == QCA6174_DEVICE_ID)
|
||||
return 0;
|
||||
|
||||
if (qmi_bypass)
|
||||
if (test_bit(QMI_BYPASS, &plat_priv->ctrl_params.quirks))
|
||||
return 0;
|
||||
|
||||
if (!config || !host_version) {
|
||||
|
|
@ -269,6 +265,9 @@ int cnss_wlan_enable(struct device *dev,
|
|||
if (mode == CNSS_WALTEST || mode == CNSS_CCPM)
|
||||
goto skip_cfg;
|
||||
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
config->send_msi_ce = true;
|
||||
|
||||
ret = cnss_wlfw_wlan_cfg_send_sync(plat_priv, config, host_version);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -286,17 +285,19 @@ int cnss_wlan_disable(struct device *dev, enum cnss_driver_mode mode)
|
|||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (plat_priv->device_id == QCA6174_DEVICE_ID)
|
||||
return 0;
|
||||
|
||||
if (qmi_bypass)
|
||||
if (test_bit(QMI_BYPASS, &plat_priv->ctrl_params.quirks))
|
||||
return 0;
|
||||
|
||||
return cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_wlan_disable);
|
||||
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
int cnss_athdiag_read(struct device *dev, u32 offset, u32 mem_type,
|
||||
u32 data_len, u8 *output)
|
||||
{
|
||||
|
|
@ -354,21 +355,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_athdiag_write);
|
||||
#else
|
||||
int cnss_athdiag_read(struct device *dev, u32 offset, u32 mem_type,
|
||||
u32 data_len, u8 *output)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_athdiag_read);
|
||||
|
||||
int cnss_athdiag_write(struct device *dev, u32 offset, u32 mem_type,
|
||||
u32 data_len, u8 *input)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_athdiag_write);
|
||||
#endif
|
||||
|
||||
int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
|
||||
{
|
||||
|
|
@ -376,6 +362,9 @@ int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
|
|||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
if (plat_priv->device_id == QCA6174_DEVICE_ID)
|
||||
return 0;
|
||||
|
||||
|
|
@ -383,16 +372,6 @@ int cnss_set_fw_log_mode(struct device *dev, u8 fw_log_mode)
|
|||
}
|
||||
EXPORT_SYMBOL(cnss_set_fw_log_mode);
|
||||
|
||||
bool *cnss_get_qmi_bypass(void)
|
||||
{
|
||||
return &qmi_bypass;
|
||||
}
|
||||
|
||||
unsigned long *cnss_get_debug_quirks(void)
|
||||
{
|
||||
return &quirks;
|
||||
}
|
||||
|
||||
static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -406,10 +385,19 @@ static int cnss_fw_mem_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv);
|
||||
cnss_wlfw_bdf_dnld_send_sync(plat_priv, CNSS_BDF_REGDB);
|
||||
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
plat_priv->ctrl_params.bdf_type = CNSS_BDF_BIN;
|
||||
|
||||
ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv,
|
||||
plat_priv->ctrl_params.bdf_type);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID)
|
||||
return 0;
|
||||
|
||||
ret = cnss_bus_load_m3(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -439,17 +427,14 @@ static int cnss_fw_ready_hdlr(struct cnss_plat_data *plat_priv)
|
|||
clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state);
|
||||
}
|
||||
|
||||
if (enable_waltest) {
|
||||
if (test_bit(ENABLE_WALTEST, &plat_priv->ctrl_params.quirks)) {
|
||||
ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
|
||||
CNSS_WALTEST);
|
||||
} else if (test_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state)) {
|
||||
ret = cnss_wlfw_wlan_mode_send_sync(plat_priv,
|
||||
CNSS_CALIBRATION);
|
||||
} else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
|
||||
ret = cnss_bus_call_driver_probe(plat_priv);
|
||||
} else {
|
||||
complete(&plat_priv->power_up_complete);
|
||||
ret = cnss_bus_call_driver_probe(plat_priv);
|
||||
}
|
||||
|
||||
if (ret && test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state))
|
||||
|
|
@ -511,6 +496,16 @@ static char *cnss_driver_event_to_str(enum cnss_driver_event_type type)
|
|||
return "POWER_UP";
|
||||
case CNSS_DRIVER_EVENT_POWER_DOWN:
|
||||
return "POWER_DOWN";
|
||||
case CNSS_DRIVER_EVENT_IDLE_RESTART:
|
||||
return "IDLE_RESTART";
|
||||
case CNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
|
||||
return "IDLE_SHUTDOWN";
|
||||
case CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM:
|
||||
return "QDSS_TRACE_REQ_MEM";
|
||||
case CNSS_DRIVER_EVENT_QDSS_TRACE_SAVE:
|
||||
return "QDSS_TRACE_SAVE";
|
||||
case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
|
||||
return "QDSS_TRACE_FREE";
|
||||
case CNSS_DRIVER_EVENT_MAX:
|
||||
return "EVENT_MAX";
|
||||
}
|
||||
|
|
@ -590,7 +585,14 @@ out:
|
|||
|
||||
unsigned int cnss_get_boot_timeout(struct device *dev)
|
||||
{
|
||||
return cnss_get_qmi_timeout();
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cnss_get_qmi_timeout(plat_priv);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_get_boot_timeout);
|
||||
|
||||
|
|
@ -653,13 +655,79 @@ EXPORT_SYMBOL(cnss_power_down);
|
|||
|
||||
int cnss_idle_restart(struct device *dev)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
unsigned int timeout;
|
||||
int ret = 0;
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Doing idle restart\n");
|
||||
|
||||
ret = cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_IDLE_RESTART,
|
||||
CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (plat_priv->device_id == QCA6174_DEVICE_ID) {
|
||||
ret = cnss_bus_call_driver_probe(plat_priv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
timeout = cnss_get_boot_timeout(dev);
|
||||
|
||||
reinit_completion(&plat_priv->power_up_complete);
|
||||
ret = wait_for_completion_timeout(&plat_priv->power_up_complete,
|
||||
msecs_to_jiffies(timeout) << 2);
|
||||
if (!ret) {
|
||||
cnss_pr_err("Timeout waiting for idle restart to complete\n");
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_idle_restart);
|
||||
|
||||
int cnss_idle_shutdown(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
int ret;
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_IN_SUSPEND_RESUME, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("System suspend or resume in progress, ignore idle shutdown\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("Doing idle shutdown\n");
|
||||
|
||||
if (!test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) &&
|
||||
!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state))
|
||||
goto skip_wait;
|
||||
|
||||
reinit_completion(&plat_priv->recovery_complete);
|
||||
ret = wait_for_completion_timeout(&plat_priv->recovery_complete,
|
||||
RECOVERY_TIMEOUT);
|
||||
if (!ret) {
|
||||
cnss_pr_err("Timeout waiting for recovery to complete\n");
|
||||
CNSS_ASSERT(0);
|
||||
}
|
||||
|
||||
skip_wait:
|
||||
return cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
|
||||
CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_idle_shutdown);
|
||||
|
||||
|
|
@ -686,6 +754,8 @@ out:
|
|||
|
||||
static void cnss_put_resources(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
cnss_put_pinctrl(plat_priv);
|
||||
cnss_put_vreg(plat_priv);
|
||||
}
|
||||
|
||||
static int cnss_modem_notifier_nb(struct notifier_block *nb,
|
||||
|
|
@ -780,9 +850,9 @@ static void cnss_unregister_esoc(struct cnss_plat_data *plat_priv)
|
|||
esoc_info = &plat_priv->esoc_info;
|
||||
|
||||
if (esoc_info->notify_modem_status)
|
||||
subsys_notif_unregister_notifier(esoc_info->
|
||||
modem_notify_handler,
|
||||
&plat_priv->modem_nb);
|
||||
subsys_notif_unregister_notifier(
|
||||
esoc_info->modem_notify_handler,
|
||||
&plat_priv->modem_nb);
|
||||
if (esoc_info->esoc_desc)
|
||||
devm_unregister_esoc_client(dev, esoc_info->esoc_desc);
|
||||
}
|
||||
|
|
@ -803,7 +873,7 @@ static int cnss_subsys_powerup(const struct subsys_desc *subsys_desc)
|
|||
}
|
||||
|
||||
if (!plat_priv->driver_state) {
|
||||
cnss_pr_dbg("Powerup is ignored\n");
|
||||
cnss_pr_dbg("subsys powerup is ignored\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -827,7 +897,7 @@ static int cnss_subsys_shutdown(const struct subsys_desc *subsys_desc,
|
|||
}
|
||||
|
||||
if (!plat_priv->driver_state) {
|
||||
cnss_pr_dbg("shutdown is ignored\n");
|
||||
cnss_pr_dbg("subsys shutdown is ignored\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -921,14 +991,15 @@ static int cnss_do_recovery(struct cnss_plat_data *plat_priv,
|
|||
if (plat_priv->device_id == QCA6174_DEVICE_ID)
|
||||
goto self_recovery;
|
||||
|
||||
if (test_bit(SKIP_RECOVERY, &quirks)) {
|
||||
if (test_bit(SKIP_RECOVERY, &plat_priv->ctrl_params.quirks)) {
|
||||
cnss_pr_dbg("Skip device recovery\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (reason) {
|
||||
case CNSS_REASON_LINK_DOWN:
|
||||
if (test_bit(LINK_DOWN_SELF_RECOVERY, &quirks))
|
||||
if (test_bit(LINK_DOWN_SELF_RECOVERY,
|
||||
&plat_priv->ctrl_params.quirks))
|
||||
goto self_recovery;
|
||||
break;
|
||||
case CNSS_REASON_RDDM:
|
||||
|
|
@ -980,16 +1051,19 @@ static int cnss_driver_recovery_hdlr(struct cnss_plat_data *plat_priv,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state)) {
|
||||
cnss_pr_err("Driver unload is in progress, ignore recovery\n");
|
||||
if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_IDLE_SHUTDOWN, &plat_priv->driver_state)) {
|
||||
cnss_pr_err("Driver unload or idle shutdown is in progress, ignore recovery\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6174_DEVICE_ID:
|
||||
if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) {
|
||||
cnss_pr_err("Driver load is in progress, ignore recovery\n");
|
||||
if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_IDLE_RESTART,
|
||||
&plat_priv->driver_state)) {
|
||||
cnss_pr_err("Driver load or idle restart is in progress, ignore recovery\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -1027,6 +1101,12 @@ void cnss_schedule_recovery(struct device *dev,
|
|||
|
||||
cnss_bus_update_status(plat_priv, CNSS_FW_DOWN);
|
||||
|
||||
if (test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_IDLE_SHUTDOWN, &plat_priv->driver_state)) {
|
||||
cnss_pr_dbg("Driver unload or idle shutdown is in progress, ignore schedule recovery\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (in_interrupt() || irqs_disabled())
|
||||
gfp = GFP_ATOMIC;
|
||||
|
||||
|
|
@ -1055,18 +1135,45 @@ int cnss_force_fw_assert(struct device *dev)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (cnss_pci_is_device_down(dev)) {
|
||||
cnss_pr_info("Device is already in bad state, ignore force assert\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
|
||||
cnss_pr_info("Recovery is already in progress, ignore forced FW assert\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
|
||||
0, NULL);
|
||||
if (in_interrupt() || irqs_disabled())
|
||||
cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
|
||||
0, NULL);
|
||||
else
|
||||
cnss_bus_force_fw_assert_hdlr(plat_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_force_fw_assert);
|
||||
static int cnss_wlfw_server_arrive_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
unsigned int bdf_type;
|
||||
|
||||
ret = cnss_wlfw_server_arrive(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!cnss_bus_req_mem_ind_valid(plat_priv)) {
|
||||
ret = cnss_wlfw_tgt_cap_send_sync(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
bdf_type = plat_priv->ctrl_params.bdf_type;
|
||||
ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv, bdf_type);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_force_collect_rddm(struct device *dev)
|
||||
{
|
||||
|
|
@ -1083,14 +1190,27 @@ int cnss_force_collect_rddm(struct device *dev)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (cnss_pci_is_device_down(dev)) {
|
||||
cnss_pr_info("Device is already in bad state, ignore force collect rddm\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) {
|
||||
cnss_pr_info("Recovery is already in progress, ignore forced collect rddm\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnss_driver_event_post(plat_priv,
|
||||
CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
|
||||
0, NULL);
|
||||
if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_IDLE_RESTART, &plat_priv->driver_state) ||
|
||||
test_bit(CNSS_DRIVER_IDLE_SHUTDOWN, &plat_priv->driver_state)) {
|
||||
cnss_pr_info("Loading/Unloading/idle restart/shutdown is in progress, ignore forced collect rddm\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = cnss_bus_force_fw_assert_hdlr(plat_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reinit_completion(&plat_priv->rddm_complete);
|
||||
ret = wait_for_completion_timeout
|
||||
|
|
@ -1123,30 +1243,6 @@ int cnss_qmi_send(struct device *dev, int type, void *cmd,
|
|||
}
|
||||
EXPORT_SYMBOL(cnss_qmi_send);
|
||||
|
||||
static int cnss_wlfw_server_arrive_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cnss_wlfw_server_arrive(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (!cnss_bus_req_mem_ind_valid(plat_priv)) {
|
||||
ret = cnss_wlfw_tgt_cap_send_sync(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = cnss_wlfw_bdf_dnld_send_sync(plat_priv);
|
||||
if (ret)
|
||||
goto out;
|
||||
/*cnss driver sends meta data report and waits for FW_READY*/
|
||||
if (cnss_bus_dev_cal_rep_valid(plat_priv))
|
||||
ret = cnss_wlfw_cal_report_send_sync(plat_priv);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_cold_boot_cal_start_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -1177,7 +1273,13 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
|
|||
|
||||
plat_priv->cal_done = true;
|
||||
cnss_wlfw_wlan_mode_send_sync(plat_priv, CNSS_OFF);
|
||||
if (plat_priv->device_id == QCN7605_DEVICE_ID ||
|
||||
plat_priv->device_id == QCN7605_STANDALONE_DEVICE_ID ||
|
||||
plat_priv->device_id == QCN7605_COMPOSITE_DEVICE_ID)
|
||||
goto skip_shutdown;
|
||||
cnss_bus_dev_shutdown(plat_priv);
|
||||
|
||||
skip_shutdown:
|
||||
complete(&plat_priv->cal_complete);
|
||||
clear_bit(CNSS_COLD_BOOT_CAL, &plat_priv->driver_state);
|
||||
|
||||
|
|
@ -1186,7 +1288,13 @@ static int cnss_cold_boot_cal_done_hdlr(struct cnss_plat_data *plat_priv)
|
|||
|
||||
static int cnss_power_up_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return cnss_bus_dev_powerup(plat_priv);
|
||||
int ret;
|
||||
|
||||
ret = cnss_bus_dev_powerup(plat_priv);
|
||||
if (ret)
|
||||
clear_bit(CNSS_DRIVER_IDLE_RESTART, &plat_priv->driver_state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv)
|
||||
|
|
@ -1196,6 +1304,109 @@ static int cnss_power_down_hdlr(struct cnss_plat_data *plat_priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cnss_qdss_trace_req_mem_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = cnss_bus_alloc_qdss_mem(plat_priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return cnss_wlfw_qdss_trace_mem_info_send_sync(plat_priv);
|
||||
}
|
||||
|
||||
static void *cnss_qdss_trace_pa_to_va(struct cnss_plat_data *plat_priv,
|
||||
u64 pa, u32 size, int *seg_id)
|
||||
{
|
||||
int i = 0;
|
||||
struct cnss_fw_mem *qdss_mem = plat_priv->qdss_mem;
|
||||
u64 offset = 0;
|
||||
void *va = NULL;
|
||||
u64 local_pa;
|
||||
u32 local_size;
|
||||
|
||||
for (i = 0; i < plat_priv->qdss_mem_seg_len; i++) {
|
||||
local_pa = (u64)qdss_mem[i].pa;
|
||||
local_size = (u32)qdss_mem[i].size;
|
||||
if (pa == local_pa && size <= local_size) {
|
||||
va = qdss_mem[i].va;
|
||||
break;
|
||||
}
|
||||
if (pa > local_pa &&
|
||||
pa < local_pa + local_size &&
|
||||
pa + size <= local_pa + local_size) {
|
||||
offset = pa - local_pa;
|
||||
va = qdss_mem[i].va + offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*seg_id = i;
|
||||
return va;
|
||||
}
|
||||
|
||||
static int cnss_qdss_trace_save_hdlr(struct cnss_plat_data *plat_priv,
|
||||
void *data)
|
||||
{
|
||||
struct cnss_qmi_event_qdss_trace_save_data *event_data = data;
|
||||
struct cnss_fw_mem *qdss_mem = plat_priv->qdss_mem;
|
||||
int ret = 0;
|
||||
int i;
|
||||
void *va = NULL;
|
||||
u64 pa;
|
||||
u32 size;
|
||||
int seg_id = 0;
|
||||
|
||||
if (!plat_priv->qdss_mem_seg_len) {
|
||||
cnss_pr_err("Memory for QDSS trace is not available\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (event_data->mem_seg_len == 0) {
|
||||
for (i = 0; i < plat_priv->qdss_mem_seg_len; i++) {
|
||||
ret = cnss_genl_send_msg(qdss_mem[i].va,
|
||||
CNSS_GENL_MSG_TYPE_QDSS,
|
||||
event_data->file_name,
|
||||
qdss_mem[i].size);
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("Fail to save QDSS data: %d\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < event_data->mem_seg_len; i++) {
|
||||
pa = event_data->mem_seg[i].addr;
|
||||
size = event_data->mem_seg[i].size;
|
||||
va = cnss_qdss_trace_pa_to_va(plat_priv, pa,
|
||||
size, &seg_id);
|
||||
if (!va) {
|
||||
cnss_pr_err("Fail to find matching va for pa 0x%llx\n",
|
||||
pa);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
ret = cnss_genl_send_msg(va, CNSS_GENL_MSG_TYPE_QDSS,
|
||||
event_data->file_name, size);
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("Fail to save QDSS data: %d\n",
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_qdss_trace_free_hdlr(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
cnss_bus_free_qdss_mem(plat_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cnss_driver_event_work(struct work_struct *work)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv =
|
||||
|
|
@ -1266,12 +1477,30 @@ static void cnss_driver_event_work(struct work_struct *work)
|
|||
case CNSS_DRIVER_EVENT_FORCE_FW_ASSERT:
|
||||
ret = cnss_bus_force_fw_assert_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_IDLE_RESTART:
|
||||
set_bit(CNSS_DRIVER_IDLE_RESTART,
|
||||
&plat_priv->driver_state);
|
||||
/* fall through */
|
||||
case CNSS_DRIVER_EVENT_POWER_UP:
|
||||
ret = cnss_power_up_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_IDLE_SHUTDOWN:
|
||||
set_bit(CNSS_DRIVER_IDLE_SHUTDOWN,
|
||||
&plat_priv->driver_state);
|
||||
/* fall through */
|
||||
case CNSS_DRIVER_EVENT_POWER_DOWN:
|
||||
ret = cnss_power_down_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM:
|
||||
ret = cnss_qdss_trace_req_mem_hdlr(plat_priv);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_QDSS_TRACE_SAVE:
|
||||
ret = cnss_qdss_trace_save_hdlr(plat_priv,
|
||||
event->data);
|
||||
break;
|
||||
case CNSS_DRIVER_EVENT_QDSS_TRACE_FREE:
|
||||
ret = cnss_qdss_trace_free_hdlr(plat_priv);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Invalid driver event type: %d",
|
||||
event->type);
|
||||
|
|
@ -1378,10 +1607,13 @@ static int cnss_register_ramdump_v1(struct cnss_plat_data *plat_priv)
|
|||
subsys_info = &plat_priv->subsys_info;
|
||||
ramdump_info = &plat_priv->ramdump_info;
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
|
||||
if (of_property_read_u32(plat_priv->dev_node,
|
||||
"qcom,wlan-ramdump-dynamic",
|
||||
&ramdump_size) == 0) {
|
||||
ramdump_info->ramdump_va = dma_alloc_coherent(dev, ramdump_size,
|
||||
&ramdump_info->ramdump_pa, GFP_KERNEL);
|
||||
ramdump_info->ramdump_va =
|
||||
dma_alloc_coherent(dev, ramdump_size,
|
||||
&ramdump_info->ramdump_pa,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (ramdump_info->ramdump_va)
|
||||
ramdump_info->ramdump_size = ramdump_size;
|
||||
|
|
@ -1441,14 +1673,14 @@ static int cnss_register_ramdump_v2(struct cnss_plat_data *plat_priv)
|
|||
struct cnss_ramdump_info_v2 *info_v2;
|
||||
struct cnss_dump_data *dump_data;
|
||||
struct msm_dump_entry dump_entry;
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
u32 ramdump_size = 0;
|
||||
|
||||
subsys_info = &plat_priv->subsys_info;
|
||||
info_v2 = &plat_priv->ramdump_info_v2;
|
||||
dump_data = &info_v2->dump_data;
|
||||
|
||||
if (of_property_read_u32(dev->of_node, "qcom,wlan-ramdump-dynamic",
|
||||
if (of_property_read_u32(plat_priv->dev_node,
|
||||
"qcom,wlan-ramdump-dynamic",
|
||||
&ramdump_size) == 0)
|
||||
info_v2->ramdump_size = ramdump_size;
|
||||
|
||||
|
|
@ -1512,16 +1744,14 @@ int cnss_register_ramdump(struct cnss_plat_data *plat_priv)
|
|||
case QCA6174_DEVICE_ID:
|
||||
ret = cnss_register_ramdump_v1(plat_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_EMULATION_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
ret = cnss_register_ramdump_v2(plat_priv);
|
||||
break;
|
||||
case QCN7605_COMPOSITE_DEVICE_ID:
|
||||
case QCN7605_STANDALONE_DEVICE_ID:
|
||||
break;
|
||||
|
||||
default:
|
||||
cnss_pr_err("Unknown device ID: 0x%lx\n", plat_priv->device_id);
|
||||
ret = -ENODEV;
|
||||
|
|
@ -1536,10 +1766,9 @@ void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv)
|
|||
case QCA6174_DEVICE_ID:
|
||||
cnss_unregister_ramdump_v1(plat_priv);
|
||||
break;
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_EMULATION_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
cnss_unregister_ramdump_v2(plat_priv);
|
||||
break;
|
||||
case QCN7605_COMPOSITE_DEVICE_ID:
|
||||
|
|
@ -1600,7 +1829,7 @@ static ssize_t cnss_fs_ready_store(struct device *dev,
|
|||
cnss_pr_dbg("File system is ready, fs_ready is %d, count is %zu\n",
|
||||
fs_ready, count);
|
||||
|
||||
if (qmi_bypass) {
|
||||
if (test_bit(QMI_BYPASS, &plat_priv->ctrl_params.quirks)) {
|
||||
cnss_pr_dbg("QMI is bypassed.\n");
|
||||
return count;
|
||||
}
|
||||
|
|
@ -1611,10 +1840,9 @@ static ssize_t cnss_fs_ready_store(struct device *dev,
|
|||
}
|
||||
|
||||
switch (plat_priv->device_id) {
|
||||
case QCA6290_EMULATION_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCA6390_EMULATION_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCN7605_DEVICE_ID:
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Not supported for device ID 0x%lx\n",
|
||||
|
|
@ -1691,6 +1919,7 @@ static int cnss_misc_init(struct cnss_plat_data *plat_priv)
|
|||
init_completion(&plat_priv->power_up_complete);
|
||||
init_completion(&plat_priv->cal_complete);
|
||||
init_completion(&plat_priv->rddm_complete);
|
||||
init_completion(&plat_priv->recovery_complete);
|
||||
mutex_init(&plat_priv->dev_lock);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1698,6 +1927,7 @@ static int cnss_misc_init(struct cnss_plat_data *plat_priv)
|
|||
|
||||
static void cnss_misc_deinit(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
complete_all(&plat_priv->recovery_complete);
|
||||
complete_all(&plat_priv->rddm_complete);
|
||||
complete_all(&plat_priv->cal_complete);
|
||||
complete_all(&plat_priv->power_up_complete);
|
||||
|
|
@ -1706,10 +1936,33 @@ static void cnss_misc_deinit(struct cnss_plat_data *plat_priv)
|
|||
del_timer(&plat_priv->fw_boot_timer);
|
||||
}
|
||||
|
||||
static void cnss_init_control_params(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
if (of_property_read_bool(plat_priv->plat_dev->dev.of_node,
|
||||
"cnss-daemon-support"))
|
||||
plat_priv->ctrl_params.quirks |= BIT(ENABLE_DAEMON_SUPPORT);
|
||||
|
||||
plat_priv->ctrl_params.mhi_timeout = CNSS_MHI_TIMEOUT_DEFAULT;
|
||||
plat_priv->ctrl_params.qmi_timeout = CNSS_QMI_TIMEOUT_DEFAULT;
|
||||
plat_priv->ctrl_params.bdf_type = CNSS_BDF_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
static void cnss_get_wlaon_pwr_ctrl_info(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
|
||||
plat_priv->set_wlaon_pwr_ctrl =
|
||||
of_property_read_bool(dev->of_node, "qcom,set-wlaon-pwr-ctrl");
|
||||
|
||||
cnss_pr_dbg("set_wlaon_pwr_ctrl is %d\n",
|
||||
plat_priv->set_wlaon_pwr_ctrl);
|
||||
}
|
||||
|
||||
static const struct platform_device_id cnss_platform_id_table[] = {
|
||||
{ .name = "qca6174", .driver_data = QCA6174_DEVICE_ID, },
|
||||
{ .name = "qca6290", .driver_data = QCA6290_DEVICE_ID, },
|
||||
{ .name = "qca6390", .driver_data = QCA6390_DEVICE_ID, },
|
||||
{ .name = "qcaconv", .driver_data = 0},
|
||||
};
|
||||
|
||||
static const struct of_device_id cnss_of_match_table[] = {
|
||||
|
|
@ -1722,10 +1975,56 @@ static const struct of_device_id cnss_of_match_table[] = {
|
|||
{
|
||||
.compatible = "qcom,cnss-qca6390",
|
||||
.data = (void *)&cnss_platform_id_table[2]},
|
||||
{
|
||||
.compatible = "qcom,cnss-qca-converged",
|
||||
.data = (void *)&cnss_platform_id_table[3]},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cnss_of_match_table);
|
||||
|
||||
struct cnss_fw_path {
|
||||
unsigned long device_id;
|
||||
const char path[CNSS_FW_PATH_MAX_LEN];
|
||||
};
|
||||
|
||||
static const struct cnss_fw_path cnss_fw_path_table[] = {
|
||||
{ QCA6174_DEVICE_ID, "qca6174/" },
|
||||
{ QCA6290_DEVICE_ID, "qca6290/" },
|
||||
{ QCA6390_DEVICE_ID, "qca6390/" },
|
||||
{ QCN7605_DEVICE_ID, "qcn7605/" },
|
||||
{ 0, "" }
|
||||
};
|
||||
|
||||
const char *cnss_get_fw_path(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
const struct cnss_fw_path *fw_path;
|
||||
const char *path;
|
||||
int size = ARRAY_SIZE(cnss_fw_path_table);
|
||||
|
||||
if (!plat_priv->is_converged_dt) {
|
||||
path = cnss_fw_path_table[size - 1].path;
|
||||
} else {
|
||||
fw_path = cnss_fw_path_table;
|
||||
while (fw_path->device_id &&
|
||||
fw_path->device_id != plat_priv->device_id) {
|
||||
fw_path++;
|
||||
}
|
||||
|
||||
path = fw_path->path;
|
||||
}
|
||||
|
||||
cnss_pr_dbg("get firmware path[%s] for device[0x%lx]\n",
|
||||
path, plat_priv->device_id);
|
||||
return path;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
cnss_is_converged_dt(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return of_property_read_bool(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,converged-dt");
|
||||
}
|
||||
|
||||
static int cnss_probe(struct platform_device *plat_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -1756,16 +2055,25 @@ static int cnss_probe(struct platform_device *plat_dev)
|
|||
}
|
||||
|
||||
plat_priv->plat_dev = plat_dev;
|
||||
plat_priv->dev_node = NULL;
|
||||
plat_priv->device_id = device_id->driver_data;
|
||||
plat_priv->bus_type = cnss_get_bus_type(plat_priv->device_id);
|
||||
plat_priv->is_converged_dt = cnss_is_converged_dt(plat_priv);
|
||||
cnss_pr_dbg("Probing platform driver from %s DT\n",
|
||||
plat_priv->is_converged_dt ? "converged" : "single");
|
||||
|
||||
plat_priv->bus_type = cnss_get_bus_type(plat_priv);
|
||||
cnss_set_plat_priv(plat_dev, plat_priv);
|
||||
platform_set_drvdata(plat_dev, plat_priv);
|
||||
INIT_LIST_HEAD(&plat_priv->vreg_list);
|
||||
|
||||
cnss_get_wlaon_pwr_ctrl_info(plat_priv);
|
||||
cnss_init_control_params(plat_priv);
|
||||
|
||||
ret = cnss_get_resources(plat_priv);
|
||||
if (ret)
|
||||
goto reset_ctx;
|
||||
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &quirks)) {
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &plat_priv->ctrl_params.quirks)) {
|
||||
ret = cnss_power_on_device(plat_priv);
|
||||
if (ret)
|
||||
goto free_res;
|
||||
|
|
@ -1803,6 +2111,10 @@ static int cnss_probe(struct platform_device *plat_dev)
|
|||
if (ret)
|
||||
goto destroy_debugfs;
|
||||
|
||||
ret = cnss_genl_init();
|
||||
if (ret < 0)
|
||||
cnss_pr_err("CNSS genl init failed %d\n", ret);
|
||||
|
||||
cnss_pr_info("Platform driver probed successfully.\n");
|
||||
|
||||
return 0;
|
||||
|
|
@ -1820,10 +2132,10 @@ unreg_bus_scale:
|
|||
unreg_esoc:
|
||||
cnss_unregister_esoc(plat_priv);
|
||||
deinit_bus:
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &quirks))
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &plat_priv->ctrl_params.quirks))
|
||||
cnss_bus_deinit(plat_priv);
|
||||
power_off:
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &quirks))
|
||||
if (!test_bit(SKIP_DEVICE_BOOT, &plat_priv->ctrl_params.quirks))
|
||||
cnss_power_off_device(plat_priv);
|
||||
free_res:
|
||||
cnss_put_resources(plat_priv);
|
||||
|
|
@ -1838,6 +2150,7 @@ static int cnss_remove(struct platform_device *plat_dev)
|
|||
{
|
||||
struct cnss_plat_data *plat_priv = platform_get_drvdata(plat_dev);
|
||||
|
||||
cnss_genl_exit();
|
||||
cnss_misc_deinit(plat_priv);
|
||||
cnss_debugfs_destroy(plat_priv);
|
||||
cnss_qmi_deinit(plat_priv);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -27,20 +27,22 @@
|
|||
#define QMI_WLFW_MAX_TIMESTAMP_LEN 32
|
||||
#define QMI_WLFW_MAX_NUM_MEM_SEG 32
|
||||
#define CNSS_RDDM_TIMEOUT_MS 20000
|
||||
#define RECOVERY_TIMEOUT 60000
|
||||
|
||||
#define CNSS_EVENT_SYNC BIT(0)
|
||||
#define CNSS_EVENT_UNINTERRUPTIBLE BIT(1)
|
||||
#define CNSS_EVENT_SYNC_UNINTERRUPTIBLE (CNSS_EVENT_SYNC | \
|
||||
CNSS_EVENT_UNINTERRUPTIBLE)
|
||||
|
||||
#define CNSS_FW_PATH_MAX_LEN 32
|
||||
|
||||
enum cnss_dev_bus_type {
|
||||
CNSS_BUS_NONE = -1,
|
||||
CNSS_BUS_PCI,
|
||||
CNSS_BUS_USB,
|
||||
};
|
||||
|
||||
struct cnss_vreg_info {
|
||||
struct regulator *reg;
|
||||
struct cnss_vreg_cfg {
|
||||
const char *name;
|
||||
u32 min_uv;
|
||||
u32 max_uv;
|
||||
|
|
@ -48,11 +50,19 @@ struct cnss_vreg_info {
|
|||
u32 delay_us;
|
||||
};
|
||||
|
||||
struct cnss_vreg_info {
|
||||
struct list_head list;
|
||||
struct regulator *reg;
|
||||
struct cnss_vreg_cfg cfg;
|
||||
u32 enabled;
|
||||
};
|
||||
|
||||
struct cnss_pinctrl_info {
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *bootstrap_active;
|
||||
struct pinctrl_state *wlan_en_active;
|
||||
struct pinctrl_state *wlan_en_sleep;
|
||||
u32 activated;
|
||||
};
|
||||
|
||||
struct cnss_subsys_info {
|
||||
|
|
@ -161,6 +171,11 @@ enum cnss_driver_event_type {
|
|||
CNSS_DRIVER_EVENT_FORCE_FW_ASSERT,
|
||||
CNSS_DRIVER_EVENT_POWER_UP,
|
||||
CNSS_DRIVER_EVENT_POWER_DOWN,
|
||||
CNSS_DRIVER_EVENT_IDLE_RESTART,
|
||||
CNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
|
||||
CNSS_DRIVER_EVENT_QDSS_TRACE_REQ_MEM,
|
||||
CNSS_DRIVER_EVENT_QDSS_TRACE_SAVE,
|
||||
CNSS_DRIVER_EVENT_QDSS_TRACE_FREE,
|
||||
CNSS_DRIVER_EVENT_CAL_UPDATE,
|
||||
CNSS_DRIVER_EVENT_CAL_DOWNLOAD,
|
||||
CNSS_DRIVER_EVENT_MAX,
|
||||
|
|
@ -173,11 +188,14 @@ enum cnss_driver_state {
|
|||
CNSS_COLD_BOOT_CAL,
|
||||
CNSS_DRIVER_LOADING,
|
||||
CNSS_DRIVER_UNLOADING,
|
||||
CNSS_DRIVER_IDLE_RESTART,
|
||||
CNSS_DRIVER_IDLE_SHUTDOWN,
|
||||
CNSS_DRIVER_PROBED,
|
||||
CNSS_DRIVER_RECOVERY,
|
||||
CNSS_FW_BOOT_RECOVERY,
|
||||
CNSS_DEV_ERR_NOTIFY,
|
||||
CNSS_DRIVER_DEBUG,
|
||||
CNSS_IN_SUSPEND_RESUME,
|
||||
};
|
||||
|
||||
struct cnss_recovery_data {
|
||||
|
|
@ -208,13 +226,49 @@ enum cnss_debug_quirks {
|
|||
SKIP_DEVICE_BOOT,
|
||||
USE_CORE_ONLY_FW,
|
||||
SKIP_RECOVERY,
|
||||
QMI_BYPASS,
|
||||
ENABLE_WALTEST,
|
||||
ENABLE_PCI_LINK_DOWN_PANIC,
|
||||
FBC_BYPASS,
|
||||
ENABLE_DAEMON_SUPPORT,
|
||||
IGNORE_PCI_LINK_FAILURE,
|
||||
};
|
||||
|
||||
enum cnss_bdf_type {
|
||||
CNSS_BDF_BIN,
|
||||
CNSS_BDF_ELF,
|
||||
CNSS_BDF_REGDB = 4,
|
||||
CNSS_BDF_DUMMY = 255,
|
||||
};
|
||||
|
||||
struct cnss_control_params {
|
||||
unsigned long quirks;
|
||||
unsigned int mhi_timeout;
|
||||
unsigned int qmi_timeout;
|
||||
unsigned int bdf_type;
|
||||
};
|
||||
|
||||
enum cnss_ce_index {
|
||||
CNSS_CE_00,
|
||||
CNSS_CE_01,
|
||||
CNSS_CE_02,
|
||||
CNSS_CE_03,
|
||||
CNSS_CE_04,
|
||||
CNSS_CE_05,
|
||||
CNSS_CE_06,
|
||||
CNSS_CE_07,
|
||||
CNSS_CE_08,
|
||||
CNSS_CE_09,
|
||||
CNSS_CE_10,
|
||||
CNSS_CE_11,
|
||||
CNSS_CE_COMMON,
|
||||
};
|
||||
|
||||
struct cnss_plat_data {
|
||||
struct platform_device *plat_dev;
|
||||
void *bus_priv;
|
||||
enum cnss_dev_bus_type bus_type;
|
||||
struct cnss_vreg_info *vreg_info;
|
||||
struct list_head vreg_list;
|
||||
struct cnss_pinctrl_info pinctrl_info;
|
||||
struct cnss_subsys_info subsys_info;
|
||||
struct cnss_ramdump_info ramdump_info;
|
||||
|
|
@ -224,6 +278,7 @@ struct cnss_plat_data {
|
|||
struct notifier_block modem_nb;
|
||||
struct cnss_platform_cap cap;
|
||||
struct pm_qos_request qos_request;
|
||||
struct cnss_device_version device_version;
|
||||
unsigned long device_id;
|
||||
enum cnss_driver_status driver_status;
|
||||
u32 recovery_count;
|
||||
|
|
@ -242,6 +297,9 @@ struct cnss_plat_data {
|
|||
u32 fw_mem_seg_len;
|
||||
struct cnss_fw_mem fw_mem[QMI_WLFW_MAX_NUM_MEM_SEG];
|
||||
struct cnss_fw_mem m3_mem;
|
||||
u32 qdss_mem_seg_len;
|
||||
struct cnss_fw_mem qdss_mem[QMI_WLFW_MAX_NUM_MEM_SEG];
|
||||
u32 *qdss_reg;
|
||||
struct cnss_pin_connect_result pin_result;
|
||||
struct dentry *root_dentry;
|
||||
atomic_t pm_count;
|
||||
|
|
@ -254,18 +312,23 @@ struct cnss_plat_data {
|
|||
u32 diag_reg_read_len;
|
||||
u8 *diag_reg_read_buf;
|
||||
bool cal_done;
|
||||
char firmware_name[13];
|
||||
char firmware_name[CNSS_FW_PATH_MAX_LEN];
|
||||
struct completion rddm_complete;
|
||||
struct completion recovery_complete;
|
||||
struct cnss_control_params ctrl_params;
|
||||
u32 is_converged_dt;
|
||||
struct device_node *dev_node;
|
||||
u8 set_wlaon_pwr_ctrl;
|
||||
};
|
||||
|
||||
struct cnss_plat_data *cnss_get_plat_priv(struct platform_device *plat_dev);
|
||||
bool *cnss_get_qmi_bypass(void);
|
||||
unsigned long *cnss_get_debug_quirks(void);
|
||||
int cnss_driver_event_post(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_driver_event_type type,
|
||||
u32 flags, void *data);
|
||||
int cnss_get_vreg(struct cnss_plat_data *plat_priv);
|
||||
int cnss_get_pinctrl(struct cnss_plat_data *plat_priv);
|
||||
void cnss_put_vreg(struct cnss_plat_data *plat_priv);
|
||||
void cnss_put_pinctrl(struct cnss_plat_data *plat_priv);
|
||||
int cnss_power_on_device(struct cnss_plat_data *plat_priv);
|
||||
void cnss_power_off_device(struct cnss_plat_data *plat_priv);
|
||||
int cnss_register_subsys(struct cnss_plat_data *plat_priv);
|
||||
|
|
@ -273,7 +336,7 @@ void cnss_unregister_subsys(struct cnss_plat_data *plat_priv);
|
|||
int cnss_register_ramdump(struct cnss_plat_data *plat_priv);
|
||||
void cnss_unregister_ramdump(struct cnss_plat_data *plat_priv);
|
||||
void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv);
|
||||
u32 cnss_get_wake_msi(struct cnss_plat_data *plat_priv);
|
||||
bool *cnss_get_qmi_bypass(void);
|
||||
bool is_qcn7605_device(u16 device_id);
|
||||
const char *cnss_get_fw_path(struct cnss_plat_data *plat_priv);
|
||||
int cnss_dev_specific_power_on(struct cnss_plat_data *plat_priv);
|
||||
|
||||
#endif /* _CNSS_MAIN_H */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -46,6 +46,16 @@ struct cnss_msi_config {
|
|||
struct cnss_msi_user *users;
|
||||
};
|
||||
|
||||
struct cnss_pci_reg {
|
||||
char *name;
|
||||
u32 offset;
|
||||
};
|
||||
|
||||
struct cnss_pci_debug_reg {
|
||||
u32 offset;
|
||||
u32 val;
|
||||
};
|
||||
|
||||
struct cnss_pci_data {
|
||||
struct pci_dev *pci_dev;
|
||||
struct cnss_plat_data *plat_priv;
|
||||
|
|
@ -70,10 +80,12 @@ struct cnss_pci_data {
|
|||
void __iomem *bar;
|
||||
struct cnss_msi_config *msi_config;
|
||||
u32 msi_ep_base_data;
|
||||
#ifdef CONFIG_MHI_BUS
|
||||
struct mhi_controller *mhi_ctrl;
|
||||
#endif
|
||||
unsigned long mhi_state;
|
||||
u32 remap_window;
|
||||
struct timer_list dev_rddm_timer;
|
||||
bool disable_pc;
|
||||
struct cnss_pci_debug_reg *debug_reg;
|
||||
};
|
||||
|
||||
static inline void cnss_set_pci_priv(struct pci_dev *pci_dev, void *data)
|
||||
|
|
@ -126,6 +138,8 @@ int cnss_resume_pci_link(struct cnss_pci_data *pci_priv);
|
|||
int cnss_pci_init(struct cnss_plat_data *plat_priv);
|
||||
void cnss_pci_deinit(struct cnss_plat_data *plat_priv);
|
||||
int cnss_pci_alloc_fw_mem(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_alloc_qdss_mem(struct cnss_pci_data *pci_priv);
|
||||
void cnss_pci_free_qdss_mem(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_load_m3(struct cnss_pci_data *pci_priv);
|
||||
int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv,
|
||||
enum cnss_mhi_state state);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -18,19 +18,25 @@
|
|||
#include "main.h"
|
||||
#include "debug.h"
|
||||
|
||||
static struct cnss_vreg_info cnss_vreg_info[] = {
|
||||
{NULL, "vdd-wlan-core", 1300000, 1300000, 0, 0},
|
||||
{NULL, "vdd-wlan-io", 1800000, 1800000, 0, 0},
|
||||
{NULL, "vdd-wlan-xtal-aon", 0, 0, 0, 0},
|
||||
{NULL, "vdd-wlan-xtal", 1800000, 1800000, 0, 2},
|
||||
{NULL, "vdd-wlan", 0, 0, 0, 0},
|
||||
{NULL, "vdd-wlan-sp2t", 2700000, 2700000, 0, 0},
|
||||
{NULL, "wlan-ant-switch", 2700000, 2700000, 20000, 0},
|
||||
{NULL, "wlan-soc-swreg", 1200000, 1200000, 0, 0},
|
||||
{NULL, "vdd-wlan-en", 0, 0, 0, 10},
|
||||
static struct cnss_vreg_cfg cnss_vreg_list[] = {
|
||||
{"vdd-wlan-core", 1300000, 1300000, 0, 0},
|
||||
{"vdd-wlan-io", 1800000, 1800000, 0, 0},
|
||||
{"vdd-wlan-xtal-aon", 0, 0, 0, 0},
|
||||
{"vdd-wlan-xtal", 1800000, 1800000, 0, 2},
|
||||
{"vdd-wlan", 0, 0, 0, 0},
|
||||
{"vdd-wlan-aon", 1055000, 1055000, 0, 0},
|
||||
{"vdd-wlan-rfa1", 1350000, 1350000, 0, 0},
|
||||
{"vdd-wlan-rfa2", 2040000, 2040000, 0, 0},
|
||||
{"vdd-wlan-rfa3", 1900000, 1900000, 0, 0},
|
||||
{"vdd-wlan-ctrl1", 0, 0, 0, 0},
|
||||
{"vdd-wlan-ctrl2", 0, 0, 0, 0},
|
||||
{"vdd-wlan-sp2t", 2700000, 2700000, 0, 0},
|
||||
{"wlan-ant-switch", 2700000, 2700000, 20000, 0},
|
||||
{"wlan-soc-swreg", 1200000, 1200000, 0, 0},
|
||||
{"vdd-wlan-en", 0, 0, 0, 10},
|
||||
};
|
||||
|
||||
#define CNSS_VREG_INFO_SIZE ARRAY_SIZE(cnss_vreg_info)
|
||||
#define CNSS_VREG_INFO_SIZE ARRAY_SIZE(cnss_vreg_list)
|
||||
#define MAX_PROP_SIZE 32
|
||||
|
||||
#define BOOTSTRAP_GPIO "qcom,enable-bootstrap-gpio"
|
||||
|
|
@ -38,71 +44,114 @@ static struct cnss_vreg_info cnss_vreg_info[] = {
|
|||
#define WLAN_EN_GPIO "wlan-en-gpio"
|
||||
#define WLAN_EN_ACTIVE "wlan_en_active"
|
||||
#define WLAN_EN_SLEEP "wlan_en_sleep"
|
||||
#define WLAN_VREGS_PROP "wlan_vregs"
|
||||
|
||||
#define BOOTSTRAP_DELAY 1000
|
||||
#define WLAN_ENABLE_DELAY 1000
|
||||
|
||||
/* For converged dt node, get the required vregs from property 'wlan_vregs',
|
||||
* which is string array; if the property is present but no value is set,
|
||||
* means no additional wlan verg is required.
|
||||
* For non-converged dt, go through all vregs in static array 'cnss_vreg_list'.
|
||||
*/
|
||||
int cnss_get_vreg(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
int i;
|
||||
struct cnss_vreg_info *vreg_info;
|
||||
struct cnss_vreg_info *vreg;
|
||||
struct device *dev;
|
||||
struct regulator *reg;
|
||||
const __be32 *prop;
|
||||
char prop_name[MAX_PROP_SIZE];
|
||||
int len;
|
||||
char prop_name[MAX_PROP_SIZE] = {0};
|
||||
int len, id_n;
|
||||
struct device_node *dt_node;
|
||||
|
||||
dev = &plat_priv->plat_dev->dev;
|
||||
|
||||
plat_priv->vreg_info = devm_kzalloc(dev, sizeof(cnss_vreg_info),
|
||||
GFP_KERNEL);
|
||||
if (!plat_priv->vreg_info) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
if (!list_empty(&plat_priv->vreg_list) &&
|
||||
!plat_priv->is_converged_dt) {
|
||||
cnss_pr_dbg("Vregs have already been updated\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(plat_priv->vreg_info, cnss_vreg_info, sizeof(cnss_vreg_info));
|
||||
dev = &plat_priv->plat_dev->dev;
|
||||
dt_node = (plat_priv->dev_node ? plat_priv->dev_node : dev->of_node);
|
||||
|
||||
for (i = 0; i < CNSS_VREG_INFO_SIZE; i++) {
|
||||
vreg_info = &plat_priv->vreg_info[i];
|
||||
reg = devm_regulator_get_optional(dev, vreg_info->name);
|
||||
if (IS_ERR(reg)) {
|
||||
ret = PTR_ERR(reg);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
else if (ret == -EPROBE_DEFER)
|
||||
cnss_pr_info("EPROBE_DEFER for regulator: %s\n",
|
||||
vreg_info->name);
|
||||
else
|
||||
cnss_pr_err("Failed to get regulator %s, err = %d\n",
|
||||
vreg_info->name, ret);
|
||||
if (plat_priv->is_converged_dt) {
|
||||
id_n = of_property_count_strings(dt_node, WLAN_VREGS_PROP);
|
||||
if (id_n <= 0) {
|
||||
if (id_n == -ENODATA) {
|
||||
cnss_pr_dbg("No additional vregs for: %s:%lx\n",
|
||||
dt_node->name,
|
||||
plat_priv->device_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnss_pr_err("property %s is invalid or missed: %s:%lx\n",
|
||||
WLAN_VREGS_PROP, dt_node->name,
|
||||
plat_priv->device_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
id_n = CNSS_VREG_INFO_SIZE;
|
||||
}
|
||||
|
||||
for (i = 0; i < id_n; i++) {
|
||||
vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
|
||||
if (!vreg) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
vreg_info->reg = reg;
|
||||
if (plat_priv->is_converged_dt) {
|
||||
ret = of_property_read_string_index(dt_node,
|
||||
WLAN_VREGS_PROP, i,
|
||||
&vreg->cfg.name);
|
||||
if (ret) {
|
||||
devm_kfree(dev, vreg);
|
||||
cnss_pr_err("Failed to read vreg ids\n");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
memcpy(&vreg->cfg, &cnss_vreg_list[i],
|
||||
sizeof(vreg->cfg));
|
||||
}
|
||||
|
||||
reg = devm_regulator_get_optional(dev, vreg->cfg.name);
|
||||
if (IS_ERR(reg)) {
|
||||
ret = PTR_ERR(reg);
|
||||
if (ret == -ENODEV) {
|
||||
devm_kfree(dev, vreg);
|
||||
continue;
|
||||
}
|
||||
else if (ret == -EPROBE_DEFER)
|
||||
cnss_pr_info("EPROBE_DEFER for regulator: %s\n",
|
||||
vreg->cfg.name);
|
||||
else
|
||||
cnss_pr_err("Failed to get regulator %s, err = %d\n",
|
||||
vreg->cfg.name, ret);
|
||||
|
||||
devm_kfree(dev, vreg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
vreg->reg = reg;
|
||||
snprintf(prop_name, MAX_PROP_SIZE, "qcom,%s-info",
|
||||
vreg_info->name);
|
||||
|
||||
prop = of_get_property(dev->of_node, prop_name, &len);
|
||||
cnss_pr_dbg("Got regulator info, name: %s, len: %d\n",
|
||||
prop_name, len);
|
||||
|
||||
vreg->cfg.name);
|
||||
prop = of_get_property(dt_node, prop_name, &len);
|
||||
if (!prop || len != (4 * sizeof(__be32))) {
|
||||
cnss_pr_dbg("Property %s %s, use default\n", prop_name,
|
||||
prop ? "invalid format" : "doesn't exist");
|
||||
} else {
|
||||
vreg_info->min_uv = be32_to_cpup(&prop[0]);
|
||||
vreg_info->max_uv = be32_to_cpup(&prop[1]);
|
||||
vreg_info->load_ua = be32_to_cpup(&prop[2]);
|
||||
vreg_info->delay_us = be32_to_cpup(&prop[3]);
|
||||
vreg->cfg.min_uv = be32_to_cpup(&prop[0]);
|
||||
vreg->cfg.max_uv = be32_to_cpup(&prop[1]);
|
||||
vreg->cfg.load_ua = be32_to_cpup(&prop[2]);
|
||||
vreg->cfg.delay_us = be32_to_cpup(&prop[3]);
|
||||
}
|
||||
|
||||
list_add_tail(&vreg->list, &plat_priv->vreg_list);
|
||||
cnss_pr_dbg("Got regulator: %s, min_uv: %u, max_uv: %u, load_ua: %u, delay_us: %u\n",
|
||||
vreg_info->name, vreg_info->min_uv,
|
||||
vreg_info->max_uv, vreg_info->load_ua,
|
||||
vreg_info->delay_us);
|
||||
vreg->cfg.name, vreg->cfg.min_uv,
|
||||
vreg->cfg.max_uv, vreg->cfg.load_ua,
|
||||
vreg->cfg.delay_us);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -110,121 +159,148 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void cnss_put_vreg(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct device *dev;
|
||||
struct cnss_vreg_info *vreg;
|
||||
|
||||
dev = &plat_priv->plat_dev->dev;
|
||||
while (!list_empty(&plat_priv->vreg_list)) {
|
||||
vreg = list_first_entry(&plat_priv->vreg_list,
|
||||
struct cnss_vreg_info, list);
|
||||
list_del(&vreg->list);
|
||||
|
||||
if (IS_ERR_OR_NULL(vreg->reg))
|
||||
continue;
|
||||
|
||||
cnss_pr_dbg("Put regulator: %s\n", vreg->cfg.name);
|
||||
devm_regulator_put(vreg->reg);
|
||||
devm_kfree(dev, vreg);
|
||||
}
|
||||
}
|
||||
|
||||
static int cnss_vreg_on(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_vreg_info *vreg_info;
|
||||
int i;
|
||||
struct cnss_vreg_info *vreg;
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < CNSS_VREG_INFO_SIZE; i++) {
|
||||
vreg_info = &plat_priv->vreg_info[i];
|
||||
|
||||
if (!vreg_info->reg)
|
||||
list_for_each_entry(vreg, &plat_priv->vreg_list, list) {
|
||||
if (IS_ERR_OR_NULL(vreg->reg))
|
||||
continue;
|
||||
|
||||
cnss_pr_dbg("Regulator %s is being enabled\n", vreg_info->name);
|
||||
if (vreg->enabled) {
|
||||
cnss_pr_dbg("Regulator %s is already enabled\n",
|
||||
vreg->cfg.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vreg_info->min_uv != 0 && vreg_info->max_uv != 0) {
|
||||
ret = regulator_set_voltage(vreg_info->reg,
|
||||
vreg_info->min_uv,
|
||||
vreg_info->max_uv);
|
||||
cnss_pr_dbg("Regulator %s is being enabled\n",
|
||||
vreg->cfg.name);
|
||||
|
||||
if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
|
||||
ret = regulator_set_voltage(vreg->reg,
|
||||
vreg->cfg.min_uv,
|
||||
vreg->cfg.max_uv);
|
||||
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to set voltage for regulator %s, min_uv: %u, max_uv: %u, err = %d\n",
|
||||
vreg_info->name, vreg_info->min_uv,
|
||||
vreg_info->max_uv, ret);
|
||||
vreg->cfg.name,
|
||||
vreg->cfg.min_uv,
|
||||
vreg->cfg.max_uv, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vreg_info->load_ua) {
|
||||
ret = regulator_set_load(vreg_info->reg,
|
||||
vreg_info->load_ua);
|
||||
if (vreg->cfg.load_ua) {
|
||||
ret = regulator_set_load(vreg->reg, vreg->cfg.load_ua);
|
||||
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("Failed to set load for regulator %s, load: %u, err = %d\n",
|
||||
vreg_info->name, vreg_info->load_ua,
|
||||
vreg->cfg.name, vreg->cfg.load_ua,
|
||||
ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vreg_info->delay_us)
|
||||
udelay(vreg_info->delay_us);
|
||||
if (vreg->cfg.delay_us)
|
||||
udelay(vreg->cfg.delay_us);
|
||||
|
||||
ret = regulator_enable(vreg_info->reg);
|
||||
ret = regulator_enable(vreg->reg);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to enable regulator %s, err = %d\n",
|
||||
vreg_info->name, ret);
|
||||
vreg->cfg.name, ret);
|
||||
break;
|
||||
}
|
||||
vreg->enabled = true;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
for (; i >= 0; i--) {
|
||||
vreg_info = &plat_priv->vreg_info[i];
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
if (!vreg_info->reg)
|
||||
continue;
|
||||
list_for_each_entry_continue_reverse(vreg, &plat_priv->vreg_list,
|
||||
list) {
|
||||
if (IS_ERR_OR_NULL(vreg->reg) || !vreg->enabled)
|
||||
continue;
|
||||
|
||||
regulator_disable(vreg_info->reg);
|
||||
if (vreg_info->load_ua)
|
||||
regulator_set_load(vreg_info->reg, 0);
|
||||
if (vreg_info->min_uv != 0 && vreg_info->max_uv != 0)
|
||||
regulator_set_voltage(vreg_info->reg, 0,
|
||||
vreg_info->max_uv);
|
||||
}
|
||||
|
||||
return ret;
|
||||
regulator_disable(vreg->reg);
|
||||
if (vreg->cfg.load_ua)
|
||||
regulator_set_load(vreg->reg, 0);
|
||||
if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0)
|
||||
regulator_set_voltage(vreg->reg, 0, vreg->cfg.max_uv);
|
||||
vreg->enabled = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cnss_vreg_off(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_vreg_info *vreg_info;
|
||||
int i;
|
||||
struct cnss_vreg_info *vreg;
|
||||
|
||||
if (!plat_priv) {
|
||||
cnss_pr_err("plat_priv is NULL!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = CNSS_VREG_INFO_SIZE - 1; i >= 0; i--) {
|
||||
vreg_info = &plat_priv->vreg_info[i];
|
||||
|
||||
if (!vreg_info->reg)
|
||||
list_for_each_entry_reverse(vreg, &plat_priv->vreg_list, list) {
|
||||
if (IS_ERR_OR_NULL(vreg->reg))
|
||||
continue;
|
||||
|
||||
cnss_pr_dbg("Regulator %s is being disabled\n",
|
||||
vreg_info->name);
|
||||
if (!vreg->enabled) {
|
||||
cnss_pr_dbg("Regulator %s is already disabled\n",
|
||||
vreg->cfg.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = regulator_disable(vreg_info->reg);
|
||||
cnss_pr_dbg("Regulator %s is being disabled\n",
|
||||
vreg->cfg.name);
|
||||
|
||||
ret = regulator_disable(vreg->reg);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to disable regulator %s, err = %d\n",
|
||||
vreg_info->name, ret);
|
||||
vreg->cfg.name, ret);
|
||||
|
||||
if (vreg_info->load_ua) {
|
||||
ret = regulator_set_load(vreg_info->reg, 0);
|
||||
if (vreg->cfg.load_ua) {
|
||||
ret = regulator_set_load(vreg->reg, 0);
|
||||
if (ret < 0)
|
||||
cnss_pr_err("Failed to set load for regulator %s, err = %d\n",
|
||||
vreg_info->name, ret);
|
||||
vreg->cfg.name, ret);
|
||||
}
|
||||
|
||||
if (vreg_info->min_uv != 0 && vreg_info->max_uv != 0) {
|
||||
ret = regulator_set_voltage(vreg_info->reg, 0,
|
||||
vreg_info->max_uv);
|
||||
if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
|
||||
ret = regulator_set_voltage(vreg->reg, 0,
|
||||
vreg->cfg.max_uv);
|
||||
if (ret)
|
||||
cnss_pr_err("Failed to set voltage for regulator %s, err = %d\n",
|
||||
vreg_info->name, ret);
|
||||
vreg->cfg.name, ret);
|
||||
}
|
||||
vreg->enabled = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -285,6 +361,18 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void cnss_put_pinctrl(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct pinctrl *pinctrl;
|
||||
|
||||
pinctrl = plat_priv->pinctrl_info.pinctrl;
|
||||
if (IS_ERR_OR_NULL(pinctrl))
|
||||
return;
|
||||
|
||||
devm_pinctrl_put(pinctrl);
|
||||
memset(&plat_priv->pinctrl_info, 0, sizeof(plat_priv->pinctrl_info));
|
||||
}
|
||||
|
||||
static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
|
||||
bool state)
|
||||
{
|
||||
|
|
@ -300,10 +388,15 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
|
|||
pinctrl_info = &plat_priv->pinctrl_info;
|
||||
|
||||
if (state) {
|
||||
if (pinctrl_info->activated) {
|
||||
cnss_pr_dbg("Pinctrl is already activated\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(pinctrl_info->bootstrap_active)) {
|
||||
ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
||||
pinctrl_info->
|
||||
bootstrap_active);
|
||||
ret = pinctrl_select_state(
|
||||
pinctrl_info->pinctrl,
|
||||
pinctrl_info->bootstrap_active);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to select bootstrap active state, err = %d\n",
|
||||
ret);
|
||||
|
|
@ -313,9 +406,9 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
|
|||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) {
|
||||
ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
||||
pinctrl_info->
|
||||
wlan_en_active);
|
||||
ret = pinctrl_select_state(
|
||||
pinctrl_info->pinctrl,
|
||||
pinctrl_info->wlan_en_active);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to select wlan_en active state, err = %d\n",
|
||||
ret);
|
||||
|
|
@ -323,7 +416,13 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
|
|||
}
|
||||
udelay(WLAN_ENABLE_DELAY);
|
||||
}
|
||||
pinctrl_info->activated = true;
|
||||
} else {
|
||||
if (!pinctrl_info->activated) {
|
||||
cnss_pr_dbg("Pinctrl is already de-activated\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) {
|
||||
ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
||||
pinctrl_info->wlan_en_sleep);
|
||||
|
|
@ -333,6 +432,7 @@ static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
|
|||
goto out;
|
||||
}
|
||||
}
|
||||
pinctrl_info->activated = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -384,3 +484,18 @@ void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv)
|
|||
|
||||
plat_priv->pin_result.host_pin_result = pin_status;
|
||||
}
|
||||
|
||||
/* If it's converged dt, get device specific regulators and enable them. */
|
||||
int cnss_dev_specific_power_on(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!plat_priv->is_converged_dt)
|
||||
return 0;
|
||||
|
||||
ret = cnss_get_vreg(plat_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return cnss_power_on_device(plat_priv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2018, 2020 The Linux Foundation. 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 and
|
||||
|
|
@ -22,18 +22,14 @@
|
|||
|
||||
#define WLFW_SERVICE_INS_ID_V01 1
|
||||
#define WLFW_CLIENT_ID 0x4b4e454c
|
||||
#define MAX_BDF_FILE_NAME 11
|
||||
#define BDF_FILE_NAME_PREFIX "bdwlan"
|
||||
#define ELF_BDF_FILE_NAME "bdwlan.elf"
|
||||
#define ELF_BDF_FILE_NAME_PREFIX "bdwlan.e"
|
||||
#define BIN_BDF_FILE_NAME "bdwlan.bin"
|
||||
#define BIN_BDF_FILE_NAME_PREFIX "bdwlan.b"
|
||||
#define REGDB_FILE_NAME "regdb.bin"
|
||||
#define DUMMY_BDF_FILE_NAME "bdwlan.dmy"
|
||||
|
||||
enum cnss_bdf_type {
|
||||
CNSS_BDF_BIN,
|
||||
CNSS_BDF_ELF,
|
||||
CNSS_BDF_DUMMY = 255,
|
||||
};
|
||||
#define CE_MSI_NAME "CE"
|
||||
|
||||
#ifdef CONFIG_CNSS2_DEBUG
|
||||
static unsigned int qmi_timeout = 10000;
|
||||
|
|
@ -249,6 +245,13 @@ static int cnss_wlfw_ind_register_send_sync(struct cnss_plat_data *plat_priv)
|
|||
req.initiate_cal_update_enable_valid = 1;
|
||||
req.initiate_cal_update_enable = 1;
|
||||
|
||||
req.qdss_trace_req_mem_enable_valid = 1;
|
||||
req.qdss_trace_req_mem_enable = 1;
|
||||
req.qdss_trace_save_enable_valid = 1;
|
||||
req.qdss_trace_save_enable = 1;
|
||||
req.qdss_trace_free_enable_valid = 1;
|
||||
req.qdss_trace_free_enable = 1;
|
||||
|
||||
req_desc.max_msg_len = WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN;
|
||||
req_desc.msg_id = QMI_WLFW_IND_REGISTER_REQ_V01;
|
||||
req_desc.ei_array = wlfw_ind_register_req_msg_v01_ei;
|
||||
|
|
@ -512,56 +515,80 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv)
|
||||
int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
|
||||
u32 bdf_type)
|
||||
{
|
||||
struct wlfw_bdf_download_req_msg_v01 *req;
|
||||
struct wlfw_bdf_download_resp_msg_v01 resp;
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
char filename[MAX_BDF_FILE_NAME];
|
||||
char filename[CNSS_FW_PATH_MAX_LEN];
|
||||
const struct firmware *fw_entry;
|
||||
const u8 *temp;
|
||||
unsigned int remaining;
|
||||
int ret = 0;
|
||||
const char *fw_path;
|
||||
|
||||
cnss_pr_dbg("Sending BDF download message, state: 0x%lx\n",
|
||||
plat_priv->driver_state);
|
||||
|
||||
req = kzalloc(sizeof(*req), GFP_KERNEL);
|
||||
if (!req) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (!req)
|
||||
return -ENOMEM;
|
||||
|
||||
fw_path = cnss_get_fw_path(plat_priv);
|
||||
switch (bdf_type) {
|
||||
case CNSS_BDF_ELF:
|
||||
if (plat_priv->board_info.board_id == 0xFF)
|
||||
snprintf(filename, sizeof(filename), ELF_BDF_FILE_NAME);
|
||||
snprintf(filename, sizeof(filename),
|
||||
"%s" ELF_BDF_FILE_NAME, fw_path);
|
||||
else if (plat_priv->board_info.board_id < 0xFF)
|
||||
snprintf(filename, sizeof(filename),
|
||||
"%s" ELF_BDF_FILE_NAME_PREFIX "%02x",
|
||||
fw_path, plat_priv->board_info.board_id);
|
||||
else
|
||||
snprintf(filename, sizeof(filename),
|
||||
ELF_BDF_FILE_NAME_PREFIX "%02x",
|
||||
plat_priv->board_info.board_id);
|
||||
"%s" BDF_FILE_NAME_PREFIX "%02x.e%02x",
|
||||
fw_path,
|
||||
plat_priv->board_info.board_id >> 8 & 0xFF,
|
||||
plat_priv->board_info.board_id & 0xFF);
|
||||
break;
|
||||
case CNSS_BDF_BIN:
|
||||
if (plat_priv->board_info.board_id == 0xFF)
|
||||
snprintf(filename, sizeof(filename), BIN_BDF_FILE_NAME);
|
||||
snprintf(filename, sizeof(filename),
|
||||
"%s" BIN_BDF_FILE_NAME, fw_path);
|
||||
else if (plat_priv->board_info.board_id < 0xFF)
|
||||
snprintf(filename, sizeof(filename),
|
||||
"%s" BIN_BDF_FILE_NAME_PREFIX "%02x",
|
||||
fw_path, plat_priv->board_info.board_id);
|
||||
else
|
||||
snprintf(filename, sizeof(filename),
|
||||
BIN_BDF_FILE_NAME_PREFIX "%02x",
|
||||
plat_priv->board_info.board_id);
|
||||
"%s" BDF_FILE_NAME_PREFIX "%02x.b%02x",
|
||||
fw_path,
|
||||
plat_priv->board_info.board_id >> 8 & 0xFF,
|
||||
plat_priv->board_info.board_id & 0xFF);
|
||||
break;
|
||||
case CNSS_BDF_REGDB:
|
||||
snprintf(filename, sizeof(filename), REGDB_FILE_NAME);
|
||||
break;
|
||||
case CNSS_BDF_DUMMY:
|
||||
cnss_pr_dbg("CNSS_BDF_DUMMY is set, sending dummy BDF\n");
|
||||
snprintf(filename, sizeof(filename), DUMMY_BDF_FILE_NAME);
|
||||
snprintf(filename, sizeof(filename),
|
||||
"%s" DUMMY_BDF_FILE_NAME, fw_path);
|
||||
temp = DUMMY_BDF_FILE_NAME;
|
||||
remaining = MAX_BDF_FILE_NAME;
|
||||
remaining = CNSS_FW_PATH_MAX_LEN;
|
||||
goto bypass_bdf;
|
||||
default:
|
||||
cnss_pr_err("Invalid BDF type: %d\n", bdf_type);
|
||||
cnss_pr_err("Invalid BDF type: %d\n",
|
||||
plat_priv->ctrl_params.bdf_type);
|
||||
ret = -EINVAL;
|
||||
goto err_req_fw;
|
||||
}
|
||||
|
||||
ret = request_firmware(&fw_entry, filename, &plat_priv->plat_dev->dev);
|
||||
if (bdf_type == CNSS_BDF_REGDB)
|
||||
ret = request_firmware_direct(&fw_entry, filename,
|
||||
&plat_priv->plat_dev->dev);
|
||||
else
|
||||
ret = request_firmware(&fw_entry, filename,
|
||||
&plat_priv->plat_dev->dev);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to load BDF: %s\n", filename);
|
||||
goto err_req_fw;
|
||||
|
|
@ -593,7 +620,7 @@ bypass_bdf:
|
|||
req->data_valid = 1;
|
||||
req->end_valid = 1;
|
||||
req->bdf_type_valid = 1;
|
||||
req->bdf_type = bdf_type;
|
||||
req->bdf_type = plat_priv->ctrl_params.bdf_type;
|
||||
|
||||
if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) {
|
||||
req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01;
|
||||
|
|
@ -608,7 +635,7 @@ bypass_bdf:
|
|||
req, sizeof(*req), &resp_desc, &resp,
|
||||
sizeof(resp), QMI_WLFW_TIMEOUT_MS);
|
||||
if (ret < 0) {
|
||||
cnss_pr_err("Failed to send BDF download request, err = %d\n",
|
||||
cnss_pr_err("Failed to wait for response of BDF download request, err: %d\n",
|
||||
ret);
|
||||
goto err_send;
|
||||
}
|
||||
|
|
@ -625,14 +652,19 @@ bypass_bdf:
|
|||
req->seg_id++;
|
||||
}
|
||||
|
||||
err_send:
|
||||
if (bdf_type != CNSS_BDF_DUMMY)
|
||||
release_firmware(fw_entry);
|
||||
err_req_fw:
|
||||
|
||||
kfree(req);
|
||||
out:
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
err_send:
|
||||
if (plat_priv->ctrl_params.bdf_type != CNSS_BDF_DUMMY)
|
||||
release_firmware(fw_entry);
|
||||
err_req_fw:
|
||||
if (bdf_type != CNSS_BDF_REGDB)
|
||||
CNSS_ASSERT(0);
|
||||
kfree(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -763,7 +795,7 @@ int cnss_wlfw_wlan_cfg_send_sync(struct cnss_plat_data *plat_priv,
|
|||
struct wlfw_wlan_cfg_req_msg_v01 req;
|
||||
struct wlfw_wlan_cfg_resp_msg_v01 resp;
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
u32 i;
|
||||
u32 i, ce_id, num_vectors, user_base_data, base_vector;
|
||||
int ret = 0;
|
||||
|
||||
cnss_pr_dbg("Sending WLAN config message, state: 0x%lx\n",
|
||||
|
|
@ -803,6 +835,18 @@ int cnss_wlfw_wlan_cfg_send_sync(struct cnss_plat_data *plat_priv,
|
|||
req.svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
|
||||
}
|
||||
|
||||
if (config->num_shadow_reg_cfg) {
|
||||
req.shadow_reg_valid = 1;
|
||||
if (config->num_shadow_reg_cfg >
|
||||
QMI_WLFW_MAX_NUM_SHADOW_REG_V01)
|
||||
req.shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01;
|
||||
else
|
||||
req.shadow_reg_len = config->num_shadow_reg_cfg;
|
||||
memcpy(req.shadow_reg, config->shadow_reg_cfg,
|
||||
sizeof(struct wlfw_shadow_reg_cfg_s_v01)
|
||||
* req.shadow_reg_len);
|
||||
}
|
||||
|
||||
req.shadow_reg_v2_valid = 1;
|
||||
if (config->num_shadow_reg_v2_cfg >
|
||||
QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01)
|
||||
|
|
@ -814,6 +858,31 @@ int cnss_wlfw_wlan_cfg_send_sync(struct cnss_plat_data *plat_priv,
|
|||
sizeof(struct wlfw_shadow_reg_v2_cfg_s_v01)
|
||||
* req.shadow_reg_v2_len);
|
||||
|
||||
if (config->rri_over_ddr_cfg_valid) {
|
||||
req.rri_over_ddr_cfg_valid = 1;
|
||||
req.rri_over_ddr_cfg.base_addr_low =
|
||||
config->rri_over_ddr_cfg.base_addr_low;
|
||||
req.rri_over_ddr_cfg.base_addr_high =
|
||||
config->rri_over_ddr_cfg.base_addr_high;
|
||||
}
|
||||
if (config->send_msi_ce) {
|
||||
ret = cnss_get_msi_assignment(plat_priv,
|
||||
CE_MSI_NAME,
|
||||
&num_vectors,
|
||||
&user_base_data,
|
||||
&base_vector);
|
||||
if (!ret) {
|
||||
req.msi_cfg_valid = 1;
|
||||
req.msi_cfg_len = QMI_WLFW_MAX_NUM_CE_V01;
|
||||
for (ce_id = 0; ce_id < QMI_WLFW_MAX_NUM_CE_V01;
|
||||
ce_id++) {
|
||||
req.msi_cfg[ce_id].ce_id = ce_id;
|
||||
req.msi_cfg[ce_id].msi_vector =
|
||||
(ce_id % num_vectors) + base_vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req_desc.max_msg_len = WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN;
|
||||
req_desc.msg_id = QMI_WLFW_WLAN_CFG_REQ_V01;
|
||||
req_desc.ei_array = wlfw_wlan_cfg_req_msg_v01_ei;
|
||||
|
|
@ -896,7 +965,7 @@ int cnss_wlfw_athdiag_read_send_sync(struct cnss_plat_data *plat_priv,
|
|||
}
|
||||
|
||||
if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
cnss_pr_err("athdiag read request failed, result: %d, err: %d\n",
|
||||
cnss_pr_err("Athdiag read request failed, result: %d, err: %d\n",
|
||||
resp->resp.result, resp->resp.error);
|
||||
ret = resp->resp.result;
|
||||
goto out;
|
||||
|
|
@ -1031,8 +1100,9 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int cnss_wlfw_cal_report_send_sync(struct cnss_plat_data *plat_priv)
|
||||
int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
/* not ready in kernel 4.9 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1087,7 +1157,7 @@ static void cnss_wlfw_clnt_ind(struct qmi_handle *handle,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int cnss_get_qmi_timeout(void)
|
||||
unsigned int cnss_get_qmi_timeout(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
cnss_pr_dbg("QMI timeout is %u ms\n", QMI_WLFW_TIMEOUT_MS);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -15,17 +15,33 @@
|
|||
|
||||
struct cnss_plat_data;
|
||||
|
||||
#define QDSS_TRACE_SEG_LEN_MAX 32
|
||||
#define QDSS_TRACE_FILE_NAME_MAX 16
|
||||
|
||||
struct cnss_mem_seg {
|
||||
u64 addr;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct cnss_qmi_event_qdss_trace_save_data {
|
||||
u32 total_size;
|
||||
u32 mem_seg_len;
|
||||
struct cnss_mem_seg mem_seg[QDSS_TRACE_SEG_LEN_MAX];
|
||||
char file_name[QDSS_TRACE_FILE_NAME_MAX + 1];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CNSS2_QMI
|
||||
#include "wlan_firmware_service_v01.h"
|
||||
|
||||
int cnss_qmi_init(struct cnss_plat_data *plat_priv);
|
||||
void cnss_qmi_deinit(struct cnss_plat_data *plat_priv);
|
||||
unsigned int cnss_get_qmi_timeout(void);
|
||||
unsigned int cnss_get_qmi_timeout(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_server_arrive(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_server_exit(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_respond_mem_send_sync(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
|
||||
u32 bdf_type);
|
||||
int cnss_wlfw_m3_dnld_send_sync(struct cnss_plat_data *plat_priv);
|
||||
int cnss_wlfw_wlan_mode_send_sync(struct cnss_plat_data *plat_priv,
|
||||
enum cnss_driver_mode mode);
|
||||
|
|
@ -40,8 +56,7 @@ int cnss_wlfw_athdiag_write_send_sync(struct cnss_plat_data *plat_priv,
|
|||
u32 data_len, u8 *data);
|
||||
int cnss_wlfw_ini_send_sync(struct cnss_plat_data *plat_priv,
|
||||
u8 fw_log_mode);
|
||||
int cnss_wlfw_cal_report_send_sync(struct cnss_plat_data *plat_priv);
|
||||
|
||||
int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv);
|
||||
#else
|
||||
#define QMI_WLFW_TIMEOUT_MS 10000
|
||||
|
||||
|
|
@ -54,12 +69,14 @@ static inline void cnss_qmi_deinit(struct cnss_plat_data *plat_priv)
|
|||
{
|
||||
}
|
||||
|
||||
static inline unsigned int cnss_get_qmi_timeout(void)
|
||||
static inline
|
||||
unsigned int cnss_get_qmi_timeout(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return QMI_WLFW_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
static inline int cnss_wlfw_server_arrive(struct cnss_plat_data *plat_priv)
|
||||
static inline int cnss_wlfw_server_arrive(struct cnss_plat_data *plat_priv,
|
||||
void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -80,7 +97,8 @@ static inline int cnss_wlfw_tgt_cap_send_sync(struct cnss_plat_data *plat_priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv)
|
||||
static inline int cnss_wlfw_bdf_dnld_send_sync(struct cnss_plat_data *plat_priv,
|
||||
u32 bdf_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -129,10 +147,10 @@ int cnss_wlfw_ini_send_sync(struct cnss_plat_data *plat_priv,
|
|||
}
|
||||
|
||||
static inline
|
||||
int cnss_wlfw_cal_report_send_sync(struct cnss_plat_data *plat_priv)
|
||||
int cnss_wlfw_qdss_trace_mem_info_send_sync(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CNSS2_QMI */
|
||||
|
||||
#endif /* _CNSS_QMI_H */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2017, 2020 The Linux Foundation. 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 and
|
||||
|
|
@ -31,7 +31,7 @@ static struct cnss_dfs_nol_info {
|
|||
int cnss_set_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 ch_count)
|
||||
{
|
||||
mutex_lock(&unsafe_channel_list_lock);
|
||||
if ((!unsafe_ch_list) || (ch_count > CNSS_MAX_CH_NUM)) {
|
||||
if (!unsafe_ch_list || ch_count > CNSS_MAX_CH_NUM) {
|
||||
mutex_unlock(&unsafe_channel_list_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2020, The Linux Foundation. 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 and
|
||||
|
|
@ -144,6 +144,57 @@ static struct elem_info wlfw_shadow_reg_v2_cfg_s_v01_ei[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct elem_info wlfw_rri_over_ddr_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_rri_over_ddr_cfg_s_v01,
|
||||
base_addr_low),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_rri_over_ddr_cfg_s_v01,
|
||||
base_addr_high),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct elem_info wlfw_msi_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_2_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u16),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_msi_cfg_s_v01,
|
||||
ce_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_2_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u16),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_msi_cfg_s_v01,
|
||||
msi_vector),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
static struct elem_info wlfw_memory_region_info_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
|
|
@ -607,6 +658,60 @@ struct elem_info wlfw_ind_register_req_msg_v01_ei[] = {
|
|||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
cal_done_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x1C,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
qdss_trace_req_mem_enable_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x1C,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
qdss_trace_req_mem_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x1D,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
qdss_trace_save_enable_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x1D,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
qdss_trace_save_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x1E,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
qdss_trace_free_enable_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x1E,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
qdss_trace_free_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
|
|
@ -921,6 +1026,53 @@ struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = {
|
|||
shadow_reg_v2),
|
||||
.ei_array = wlfw_shadow_reg_v2_cfg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x15,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
rri_over_ddr_cfg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct wlfw_rri_over_ddr_cfg_s_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x15,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
rri_over_ddr_cfg),
|
||||
.ei_array = wlfw_rri_over_ddr_cfg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
msi_cfg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
msi_cfg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_CE_V01,
|
||||
.elem_size = sizeof(struct wlfw_msi_cfg_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
msi_cfg),
|
||||
.ei_array = wlfw_msi_cfg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
|
|
@ -1077,6 +1229,42 @@ struct elem_info wlfw_cap_resp_msg_v01_ei[] = {
|
|||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
num_macs),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
voltage_mv_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x16,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
voltage_mv),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x17,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
time_freq_hz_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x17,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
time_freq_hz),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
|
|
@ -1316,9 +1504,9 @@ struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = {
|
|||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(
|
||||
struct wlfw_initiate_cal_download_ind_msg_v01,
|
||||
total_size_valid),
|
||||
.offset = offsetof(struct
|
||||
wlfw_initiate_cal_download_ind_msg_v01,
|
||||
total_size_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
|
|
@ -1326,9 +1514,9 @@ struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = {
|
|||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(
|
||||
struct wlfw_initiate_cal_download_ind_msg_v01,
|
||||
total_size),
|
||||
.offset = offsetof(struct
|
||||
wlfw_initiate_cal_download_ind_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
|
|
@ -1336,9 +1524,9 @@ struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = {
|
|||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(
|
||||
struct wlfw_initiate_cal_download_ind_msg_v01,
|
||||
cal_data_location_valid),
|
||||
.offset = offsetof(struct
|
||||
wlfw_initiate_cal_download_ind_msg_v01,
|
||||
cal_data_location_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
|
|
@ -1346,9 +1534,9 @@ struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = {
|
|||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(
|
||||
struct wlfw_initiate_cal_download_ind_msg_v01,
|
||||
cal_data_location),
|
||||
.offset = offsetof(struct
|
||||
wlfw_initiate_cal_download_ind_msg_v01,
|
||||
cal_data_location),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
|
|
@ -1538,8 +1726,8 @@ struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[] = {
|
|||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_initiate_cal_update_ind_msg_v01,
|
||||
cal_data_location_valid),
|
||||
wlfw_initiate_cal_update_ind_msg_v01,
|
||||
cal_data_location_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
|
|
@ -1548,8 +1736,8 @@ struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[] = {
|
|||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_initiate_cal_update_ind_msg_v01,
|
||||
cal_data_location),
|
||||
wlfw_initiate_cal_update_ind_msg_v01,
|
||||
cal_data_location),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
|
|
@ -2719,3 +2907,554 @@ struct elem_info wlfw_cal_done_ind_msg_v01_ei[] = {
|
|||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_req_mem_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_req_mem_ind_msg_v01,
|
||||
mem_seg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01,
|
||||
.elem_size = sizeof(struct wlfw_mem_seg_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_req_mem_ind_msg_v01,
|
||||
mem_seg),
|
||||
.ei_array = wlfw_mem_seg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_mem_info_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mem_info_req_msg_v01,
|
||||
mem_seg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01,
|
||||
.elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mem_info_req_msg_v01,
|
||||
mem_seg),
|
||||
.ei_array = wlfw_mem_seg_resp_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_mem_info_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mem_info_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_save_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
source),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
mem_seg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
mem_seg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01,
|
||||
.elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
mem_seg),
|
||||
.ei_array = wlfw_mem_seg_resp_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
file_name_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRING,
|
||||
.elem_len = QMI_WLFW_MAX_STR_LEN_V01 + 1,
|
||||
.elem_size = sizeof(char),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_save_ind_msg_v01,
|
||||
file_name),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_data_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_req_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_data_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
total_size_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
seg_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
data_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u16),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
data_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = QMI_WLFW_MAX_DATA_SIZE_V01,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
data),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
end_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_data_resp_msg_v01,
|
||||
end),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_config_download_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
total_size_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
seg_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u32),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
data_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u16),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
data_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = QMI_WLFW_MAX_DATA_SIZE_V01,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
data),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
end_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_req_msg_v01,
|
||||
end),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_config_download_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_config_download_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_mode_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mode_req_msg_v01,
|
||||
mode_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_qdss_trace_mode_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mode_req_msg_v01,
|
||||
mode),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mode_req_msg_v01,
|
||||
option_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_8_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u64),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mode_req_msg_v01,
|
||||
option),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_mode_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_mode_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_qdss_trace_free_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_free_ind_msg_v01,
|
||||
mem_seg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_free_ind_msg_v01,
|
||||
mem_seg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_MEM_SEG_V01,
|
||||
.elem_size = sizeof(struct wlfw_mem_seg_resp_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct
|
||||
wlfw_qdss_trace_free_ind_msg_v01,
|
||||
mem_seg),
|
||||
.ei_array = wlfw_mem_seg_resp_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_shutdown_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_shutdown_req_msg_v01,
|
||||
shutdown_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(u8),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_shutdown_req_msg_v01,
|
||||
shutdown),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_shutdown_resp_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(struct qmi_response_type_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct wlfw_shutdown_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = qmi_response_type_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2018, 2020 The Linux Foundation. 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 and
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025
|
||||
#define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037
|
||||
#define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_V01 0x0044
|
||||
#define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A
|
||||
#define QMI_WLFW_CAL_DONE_IND_V01 0x003E
|
||||
#define QMI_WLFW_HOST_CAP_REQ_V01 0x0034
|
||||
|
|
@ -36,6 +37,9 @@
|
|||
#define QMI_WLFW_XO_CAL_IND_V01 0x003D
|
||||
#define QMI_WLFW_INI_RESP_V01 0x002F
|
||||
#define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026
|
||||
#define QMI_WLFW_QDSS_TRACE_MEM_INFO_REQ_V01 0x0040
|
||||
#define QMI_WLFW_QDSS_TRACE_REQ_MEM_IND_V01 0x003F
|
||||
#define QMI_WLFW_SHUTDOWN_RESP_V01 0x0043
|
||||
#define QMI_WLFW_MAC_ADDR_RESP_V01 0x0033
|
||||
#define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028
|
||||
#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034
|
||||
|
|
@ -44,29 +48,38 @@
|
|||
#define QMI_WLFW_WLAN_MODE_REQ_V01 0x0022
|
||||
#define QMI_WLFW_IND_REGISTER_REQ_V01 0x0020
|
||||
#define QMI_WLFW_WLAN_CFG_RESP_V01 0x0023
|
||||
#define QMI_WLFW_QDSS_TRACE_MODE_REQ_V01 0x0045
|
||||
#define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
|
||||
#define QMI_WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_RESP_V01 0x0044
|
||||
#define QMI_WLFW_REJUVENATE_IND_V01 0x0039
|
||||
#define QMI_WLFW_DYNAMIC_FEATURE_MASK_REQ_V01 0x003B
|
||||
#define QMI_WLFW_ATHDIAG_WRITE_REQ_V01 0x0031
|
||||
#define QMI_WLFW_WLAN_MODE_RESP_V01 0x0022
|
||||
#define QMI_WLFW_RESPOND_MEM_REQ_V01 0x0036
|
||||
#define QMI_WLFW_QDSS_TRACE_MODE_RESP_V01 0x0045
|
||||
#define QMI_WLFW_PIN_CONNECT_RESULT_IND_V01 0x002C
|
||||
#define QMI_WLFW_FW_READY_IND_V01 0x0021
|
||||
#define QMI_WLFW_QDSS_TRACE_SAVE_IND_V01 0x0041
|
||||
#define QMI_WLFW_QDSS_TRACE_MEM_INFO_RESP_V01 0x0040
|
||||
#define QMI_WLFW_MSA_READY_RESP_V01 0x002E
|
||||
#define QMI_WLFW_QDSS_TRACE_DATA_REQ_V01 0x0042
|
||||
#define QMI_WLFW_CAL_UPDATE_REQ_V01 0x0029
|
||||
#define QMI_WLFW_INI_REQ_V01 0x002F
|
||||
#define QMI_WLFW_BDF_DOWNLOAD_RESP_V01 0x0025
|
||||
#define QMI_WLFW_REJUVENATE_ACK_RESP_V01 0x003A
|
||||
#define QMI_WLFW_MSA_INFO_RESP_V01 0x002D
|
||||
#define QMI_WLFW_MSA_READY_REQ_V01 0x002E
|
||||
#define QMI_WLFW_QDSS_TRACE_DATA_RESP_V01 0x0042
|
||||
#define QMI_WLFW_CAP_RESP_V01 0x0024
|
||||
#define QMI_WLFW_REJUVENATE_ACK_REQ_V01 0x003A
|
||||
#define QMI_WLFW_ATHDIAG_READ_RESP_V01 0x0030
|
||||
#define QMI_WLFW_SHUTDOWN_REQ_V01 0x0043
|
||||
#define QMI_WLFW_VBATT_REQ_V01 0x0032
|
||||
#define QMI_WLFW_MAC_ADDR_REQ_V01 0x0033
|
||||
#define QMI_WLFW_RESPOND_MEM_RESP_V01 0x0036
|
||||
#define QMI_WLFW_VBATT_RESP_V01 0x0032
|
||||
#define QMI_WLFW_MSA_INFO_REQ_V01 0x002D
|
||||
#define QMI_WLFW_QDSS_TRACE_FREE_IND_V01 0x0046
|
||||
#define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027
|
||||
#define QMI_WLFW_ATHDIAG_READ_REQ_V01 0x0030
|
||||
#define QMI_WLFW_WLAN_CFG_REQ_V01 0x0023
|
||||
|
|
@ -129,9 +142,17 @@ enum wlfw_mem_type_enum_v01 {
|
|||
QMI_WLFW_MEM_M3_V01 = 3,
|
||||
QMI_WLFW_MEM_CAL_V01 = 4,
|
||||
QMI_WLFW_MEM_DPD_V01 = 5,
|
||||
QMI_WLFW_MEM_QDSS_V01 = 6,
|
||||
WLFW_MEM_TYPE_ENUM_MAX_VAL_V01 = INT_MAX,
|
||||
};
|
||||
|
||||
enum wlfw_qdss_trace_mode_enum_v01 {
|
||||
WLFW_QDSS_TRACE_MODE_ENUM_MIN_VAL_V01 = INT_MIN,
|
||||
QMI_WLFW_QDSS_TRACE_OFF_V01 = 0,
|
||||
QMI_WLFW_QDSS_TRACE_ON_V01 = 1,
|
||||
WLFW_QDSS_TRACE_MODE_ENUM_MAX_VAL_V01 = INT_MAX,
|
||||
};
|
||||
|
||||
#define QMI_WLFW_CE_ATTR_FLAGS_V01 ((u32)0x00)
|
||||
#define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((u32)0x01)
|
||||
#define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((u32)0x02)
|
||||
|
|
@ -170,6 +191,16 @@ struct wlfw_shadow_reg_v2_cfg_s_v01 {
|
|||
u32 addr;
|
||||
};
|
||||
|
||||
struct wlfw_rri_over_ddr_cfg_s_v01 {
|
||||
u32 base_addr_low;
|
||||
u32 base_addr_high;
|
||||
};
|
||||
|
||||
struct wlfw_msi_cfg_s_v01 {
|
||||
u16 ce_id;
|
||||
u16 msi_vector;
|
||||
};
|
||||
|
||||
struct wlfw_memory_region_info_s_v01 {
|
||||
u64 region_addr;
|
||||
u32 size;
|
||||
|
|
@ -239,9 +270,15 @@ struct wlfw_ind_register_req_msg_v01 {
|
|||
u8 xo_cal_enable;
|
||||
u8 cal_done_enable_valid;
|
||||
u8 cal_done_enable;
|
||||
u8 qdss_trace_req_mem_enable_valid;
|
||||
u8 qdss_trace_req_mem_enable;
|
||||
u8 qdss_trace_save_enable_valid;
|
||||
u8 qdss_trace_save_enable;
|
||||
u8 qdss_trace_free_enable_valid;
|
||||
u8 qdss_trace_free_enable;
|
||||
};
|
||||
|
||||
#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 54
|
||||
#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 66
|
||||
extern struct elem_info wlfw_ind_register_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_ind_register_resp_msg_v01 {
|
||||
|
|
@ -312,9 +349,14 @@ struct wlfw_wlan_cfg_req_msg_v01 {
|
|||
u32 shadow_reg_v2_len;
|
||||
struct wlfw_shadow_reg_v2_cfg_s_v01
|
||||
shadow_reg_v2[QMI_WLFW_MAX_NUM_SHADOW_REG_V2_V01];
|
||||
u8 rri_over_ddr_cfg_valid;
|
||||
struct wlfw_rri_over_ddr_cfg_s_v01 rri_over_ddr_cfg;
|
||||
u8 msi_cfg_valid;
|
||||
u32 msi_cfg_len;
|
||||
struct wlfw_msi_cfg_s_v01 msi_cfg[QMI_WLFW_MAX_NUM_CE_V01];
|
||||
};
|
||||
|
||||
#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 803
|
||||
#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 866
|
||||
extern struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_wlan_cfg_resp_msg_v01 {
|
||||
|
|
@ -345,9 +387,13 @@ struct wlfw_cap_resp_msg_v01 {
|
|||
char fw_build_id[QMI_WLFW_MAX_BUILD_ID_LEN_V01 + 1];
|
||||
u8 num_macs_valid;
|
||||
u8 num_macs;
|
||||
u8 voltage_mv_valid;
|
||||
u32 voltage_mv;
|
||||
u8 time_freq_hz_valid;
|
||||
u32 time_freq_hz;
|
||||
};
|
||||
|
||||
#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 207
|
||||
#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 221
|
||||
extern struct elem_info wlfw_cap_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_bdf_download_req_msg_v01 {
|
||||
|
|
@ -737,4 +783,126 @@ struct wlfw_cal_done_ind_msg_v01 {
|
|||
#define WLFW_CAL_DONE_IND_MSG_V01_MAX_MSG_LEN 0
|
||||
extern struct elem_info wlfw_cal_done_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_req_mem_ind_msg_v01 {
|
||||
u32 mem_seg_len;
|
||||
struct wlfw_mem_seg_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_REQ_MEM_IND_MSG_V01_MAX_MSG_LEN 1124
|
||||
extern struct elem_info wlfw_qdss_trace_req_mem_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_mem_info_req_msg_v01 {
|
||||
u32 mem_seg_len;
|
||||
struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_MEM_INFO_REQ_MSG_V01_MAX_MSG_LEN 548
|
||||
extern struct elem_info wlfw_qdss_trace_mem_info_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_mem_info_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_MEM_INFO_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_qdss_trace_mem_info_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_save_ind_msg_v01 {
|
||||
u32 source;
|
||||
u32 total_size;
|
||||
u8 mem_seg_valid;
|
||||
u32 mem_seg_len;
|
||||
struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
|
||||
u8 file_name_valid;
|
||||
char file_name[QMI_WLFW_MAX_STR_LEN_V01 + 1];
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_SAVE_IND_MSG_V01_MAX_MSG_LEN 581
|
||||
extern struct elem_info wlfw_qdss_trace_save_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_data_req_msg_v01 {
|
||||
u32 seg_id;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_DATA_REQ_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_qdss_trace_data_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_data_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
u8 total_size_valid;
|
||||
u32 total_size;
|
||||
u8 seg_id_valid;
|
||||
u32 seg_id;
|
||||
u8 data_valid;
|
||||
u32 data_len;
|
||||
u8 data[QMI_WLFW_MAX_DATA_SIZE_V01];
|
||||
u8 end_valid;
|
||||
u8 end;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_DATA_RESP_MSG_V01_MAX_MSG_LEN 6174
|
||||
extern struct elem_info wlfw_qdss_trace_data_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_config_download_req_msg_v01 {
|
||||
u8 total_size_valid;
|
||||
u32 total_size;
|
||||
u8 seg_id_valid;
|
||||
u32 seg_id;
|
||||
u8 data_valid;
|
||||
u32 data_len;
|
||||
u8 data[QMI_WLFW_MAX_DATA_SIZE_V01];
|
||||
u8 end_valid;
|
||||
u8 end;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6167
|
||||
extern struct elem_info wlfw_qdss_trace_config_download_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_config_download_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_CONFIG_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_qdss_trace_config_download_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_mode_req_msg_v01 {
|
||||
u8 mode_valid;
|
||||
enum wlfw_qdss_trace_mode_enum_v01 mode;
|
||||
u8 option_valid;
|
||||
u64 option;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_MODE_REQ_MSG_V01_MAX_MSG_LEN 18
|
||||
extern struct elem_info wlfw_qdss_trace_mode_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_mode_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_MODE_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_qdss_trace_mode_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_qdss_trace_free_ind_msg_v01 {
|
||||
u8 mem_seg_valid;
|
||||
u32 mem_seg_len;
|
||||
struct wlfw_mem_seg_resp_s_v01 mem_seg[QMI_WLFW_MAX_NUM_MEM_SEG_V01];
|
||||
};
|
||||
|
||||
#define WLFW_QDSS_TRACE_FREE_IND_MSG_V01_MAX_MSG_LEN 548
|
||||
extern struct elem_info wlfw_qdss_trace_free_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_shutdown_req_msg_v01 {
|
||||
u8 shutdown_valid;
|
||||
u8 shutdown;
|
||||
};
|
||||
|
||||
#define WLFW_SHUTDOWN_REQ_MSG_V01_MAX_MSG_LEN 4
|
||||
extern struct elem_info wlfw_shutdown_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_shutdown_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
|
||||
#define WLFW_SHUTDOWN_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_shutdown_resp_msg_v01_ei[];
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,9 +27,11 @@
|
|||
|
||||
enum cnss_bus_width_type {
|
||||
CNSS_BUS_WIDTH_NONE,
|
||||
CNSS_BUS_WIDTH_IDLE,
|
||||
CNSS_BUS_WIDTH_LOW,
|
||||
CNSS_BUS_WIDTH_MEDIUM,
|
||||
CNSS_BUS_WIDTH_HIGH
|
||||
CNSS_BUS_WIDTH_HIGH,
|
||||
CNSS_BUS_WIDTH_VERY_HIGH,
|
||||
};
|
||||
|
||||
enum cnss_platform_cap_flag {
|
||||
|
|
@ -158,6 +160,7 @@ struct cnss_wlan_enable_cfg {
|
|||
struct cnss_shadow_reg_v2_cfg *shadow_reg_v2_cfg;
|
||||
bool rri_over_ddr_cfg_valid;
|
||||
struct cnss_rri_over_ddr_cfg rri_over_ddr_cfg;
|
||||
bool send_msi_ce;
|
||||
};
|
||||
|
||||
enum cnss_driver_mode {
|
||||
|
|
|
|||
Loading…
Reference in a new issue