net: icnss: Add snapshot of icnss driver
This is a snapshot of the icnss driver and associated files as of msm-3.18 commit: e70ad0cd5efdd9dc91a77dcdac31d6132e1315c1 (Promotion of kernel.lnx. 3.18-151201.) Signed-off-by: Yue Ma <yuem@codeaurora.org>
This commit is contained in:
parent
f590819cde
commit
791a6a69a5
7 changed files with 2338 additions and 0 deletions
36
Documentation/devicetree/bindings/cnss/icnss.txt
Normal file
36
Documentation/devicetree/bindings/cnss/icnss.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
* Qualcomm Technologies Inc Q6 Integrated connectivity Platform Driver
|
||||
|
||||
This platform driver adds support for the Integrated WLAN that runs
|
||||
on Q6 based platforms. WLAN FW on these architecture runs on Q6. This
|
||||
platform driver communicates with WLAN FW over QMI, WLAN on/off messages
|
||||
to FW are communicated thru this interface. This driver also listens to
|
||||
WLAN PD restart notifications.
|
||||
|
||||
Required properties:
|
||||
- compatible: "qcom,icnss"
|
||||
- reg: Memory regions defined as starting address and size
|
||||
- reg-names: Names of the memory regions defined in reg entry
|
||||
- interrupts: Copy engine interrupt table
|
||||
|
||||
Optional properties:
|
||||
|
||||
Example:
|
||||
|
||||
qcom,icnss@0a000000 {
|
||||
compatible = "qcom,icnss";
|
||||
reg = <0x0a000000 0x1000000>;
|
||||
reg-names = "membase";
|
||||
interrupts =
|
||||
<0 130 0 /* CE0 */ >,
|
||||
<0 131 0 /* CE1 */ >,
|
||||
<0 132 0 /* CE2 */ >,
|
||||
<0 133 0 /* CE3 */ >,
|
||||
<0 134 0 /* CE4 */ >,
|
||||
<0 135 0 /* CE5 */ >,
|
||||
<0 136 0 /* CE6 */ >,
|
||||
<0 137 0 /* CE7 */ >,
|
||||
<0 138 0 /* CE8 */ >,
|
||||
<0 139 0 /* CE9 */ >,
|
||||
<0 140 0 /* CE10 */ >,
|
||||
<0 141 0 /* CE11 */ >;
|
||||
};
|
|
@ -343,6 +343,14 @@ config QCOM_MEMORY_DUMP_V2
|
|||
of deadlocks or cpu hangs these dump regions are captured to
|
||||
give a snapshot of the system at the time of the crash.
|
||||
|
||||
config ICNSS
|
||||
tristate "Platform driver for Q6 integrated connectivity"
|
||||
---help---
|
||||
This module adds support for Q6 integrated WLAN connectivity
|
||||
subsystem. This module is responsible for communicating WLAN on/off
|
||||
control messages to FW over QMI channel. It is also responsible for
|
||||
handling WLAN PD restart notifications.
|
||||
|
||||
config MSM_SECURE_BUFFER
|
||||
bool "Helper functions for securing buffers through TZ"
|
||||
help
|
||||
|
|
|
@ -53,6 +53,7 @@ obj-$(CONFIG_QCOM_MEMORY_DUMP) += memory_dump.o
|
|||
obj-$(CONFIG_QCOM_MEMORY_DUMP_V2) += memory_dump_v2.o
|
||||
obj-$(CONFIG_QCOM_WATCHDOG_V2) += watchdog_v2.o
|
||||
obj-$(CONFIG_TRACER_PKT) += tracer_pkt.o
|
||||
obj-$(CONFIG_ICNSS) += icnss.o wlan_firmware_service_v01.o
|
||||
obj-$(CONFIG_SOC_BUS) += socinfo.o
|
||||
obj-$(CONFIG_QCOM_BUS_SCALING) += msm_bus/
|
||||
obj-$(CONFIG_MSM_SECURE_BUFFER) += secure_buffer.o
|
||||
|
|
946
drivers/soc/qcom/icnss.c
Normal file
946
drivers/soc/qcom/icnss.c
Normal file
|
@ -0,0 +1,946 @@
|
|||
/* Copyright (c) 2015, 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.
|
||||
*/
|
||||
#include <linux/export.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/qmi_encdec.h>
|
||||
#include <soc/qcom/memory_dump.h>
|
||||
#include <soc/qcom/icnss.h>
|
||||
#include <soc/qcom/msm_qmi_interface.h>
|
||||
|
||||
#include "wlan_firmware_service_v01.h"
|
||||
|
||||
enum icnss_qmi_event_type {
|
||||
ICNSS_QMI_EVENT_SERVER_ARRIVE,
|
||||
ICNSS_QMI_EVENT_SERVER_EXIT,
|
||||
ICNSS_QMI_EVENT_FW_READY_IND,
|
||||
};
|
||||
|
||||
struct icnss_qmi_event {
|
||||
struct list_head list;
|
||||
enum icnss_qmi_event_type type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
#define ICNSS_PANIC 1
|
||||
#define WLFW_TIMEOUT_MS 3000
|
||||
#define WLFW_SERVICE_INS_ID_V01 0
|
||||
#define ICNSS_WLFW_QMI_CONNECTED BIT(0)
|
||||
#define ICNSS_FW_READY BIT(1)
|
||||
|
||||
#define ICNSS_IS_WLFW_QMI_CONNECTED(_state) \
|
||||
((_state) & ICNSS_WLFW_QMI_CONNECTED)
|
||||
#define ICNSS_IS_FW_READY(_state) ((_state) & ICNSS_FW_READY)
|
||||
|
||||
#ifdef ICNSS_PANIC
|
||||
#define ICNSS_ASSERT(_condition) do { \
|
||||
if (!(_condition)) { \
|
||||
pr_err("ICNSS ASSERT in %s Line %d\n", \
|
||||
__func__, __LINE__); \
|
||||
BUG_ON(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define ICNSS_ASSERT(_condition) do { \
|
||||
if (!(_condition)) { \
|
||||
pr_err("ICNSS ASSERT in %s Line %d\n", \
|
||||
__func__, __LINE__); \
|
||||
WARN_ON(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
struct ce_irq_list {
|
||||
int irq;
|
||||
irqreturn_t (*handler)(int, void *);
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct platform_device *pdev;
|
||||
struct icnss_driver_ops *ops;
|
||||
struct ce_irq_list ce_irq_list[ICNSS_MAX_IRQ_REGISTRATIONS];
|
||||
u32 ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS];
|
||||
phys_addr_t mem_base_pa;
|
||||
void __iomem *mem_base_va;
|
||||
struct qmi_handle *wlfw_clnt;
|
||||
struct list_head qmi_event_list;
|
||||
spinlock_t qmi_event_lock;
|
||||
struct work_struct qmi_event_work;
|
||||
struct work_struct qmi_recv_msg_work;
|
||||
struct workqueue_struct *qmi_event_wq;
|
||||
uint32_t state;
|
||||
u32 board_id;
|
||||
u32 num_peers;
|
||||
u32 mac_version;
|
||||
char fw_version[QMI_WLFW_MAX_STR_LEN_V01 + 1];
|
||||
} *penv;
|
||||
|
||||
static int icnss_qmi_event_post(enum icnss_qmi_event_type type, void *data)
|
||||
{
|
||||
struct icnss_qmi_event *event = NULL;
|
||||
unsigned long flags;
|
||||
int gfp = GFP_KERNEL;
|
||||
|
||||
if (in_interrupt() || irqs_disabled())
|
||||
gfp = GFP_ATOMIC;
|
||||
|
||||
event = kzalloc(sizeof(*event), gfp);
|
||||
if (event == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
event->type = type;
|
||||
event->data = data;
|
||||
spin_lock_irqsave(&penv->qmi_event_lock, flags);
|
||||
list_add_tail(&event->list, &penv->qmi_event_list);
|
||||
spin_unlock_irqrestore(&penv->qmi_event_lock, flags);
|
||||
|
||||
queue_work(penv->qmi_event_wq, &penv->qmi_event_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wlfw_ind_register_send_sync_msg(void)
|
||||
{
|
||||
int ret;
|
||||
struct wlfw_ind_register_req_msg_v01 req;
|
||||
struct wlfw_ind_register_resp_msg_v01 resp;
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
|
||||
if (!penv || !penv->wlfw_clnt) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
req.fw_ready_enable_valid = 1;
|
||||
req.fw_ready_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;
|
||||
|
||||
resp_desc.max_msg_len = WLFW_IND_REGISTER_RESP_MSG_V01_MAX_MSG_LEN;
|
||||
resp_desc.msg_id = QMI_WLFW_IND_REGISTER_RESP_V01;
|
||||
resp_desc.ei_array = wlfw_ind_register_resp_msg_v01_ei;
|
||||
|
||||
ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req),
|
||||
&resp_desc, &resp, sizeof(resp),
|
||||
WLFW_TIMEOUT_MS);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: send req failed %d\n", __func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
pr_err("%s: QMI request failed %d %d\n",
|
||||
__func__, resp.resp.result, resp.resp.error);
|
||||
ret = resp.resp.result;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wlfw_cap_send_sync_msg(void)
|
||||
{
|
||||
int ret;
|
||||
struct wlfw_cap_req_msg_v01 req;
|
||||
struct wlfw_cap_resp_msg_v01 resp;
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
|
||||
if (!penv || !penv->wlfw_clnt) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
req_desc.max_msg_len = WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN;
|
||||
req_desc.msg_id = QMI_WLFW_CAP_REQ_V01;
|
||||
req_desc.ei_array = wlfw_cap_req_msg_v01_ei;
|
||||
|
||||
resp_desc.max_msg_len = WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN;
|
||||
resp_desc.msg_id = QMI_WLFW_CAP_RESP_V01;
|
||||
resp_desc.ei_array = wlfw_cap_resp_msg_v01_ei;
|
||||
|
||||
ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req),
|
||||
&resp_desc, &resp, sizeof(resp),
|
||||
WLFW_TIMEOUT_MS);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: send req failed %d\n", __func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
pr_err("%s: QMI request failed %d %d\n",
|
||||
__func__, resp.resp.result, resp.resp.error);
|
||||
ret = resp.resp.result;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* store cap locally */
|
||||
if (resp.board_id_valid)
|
||||
penv->board_id = resp.board_id;
|
||||
if (resp.num_peers_valid)
|
||||
penv->num_peers = resp.num_peers;
|
||||
if (resp.mac_version_valid)
|
||||
penv->mac_version = resp.mac_version;
|
||||
if (resp.fw_version_valid)
|
||||
strlcpy(penv->fw_version, resp.fw_version,
|
||||
QMI_WLFW_MAX_STR_LEN_V01 + 1);
|
||||
|
||||
pr_debug("%s: board_id:0x%0x num_peers: %d mac_version: 0x%0x fw_version: %s",
|
||||
__func__, penv->board_id, penv->num_peers,
|
||||
penv->mac_version, penv->fw_version);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wlfw_wlan_mode_send_sync_msg(enum wlfw_driver_mode_enum_v01 mode)
|
||||
{
|
||||
int ret;
|
||||
struct wlfw_wlan_mode_req_msg_v01 req;
|
||||
struct wlfw_wlan_mode_resp_msg_v01 resp;
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
|
||||
if (!penv || !penv->wlfw_clnt) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
req.mode = mode;
|
||||
|
||||
req_desc.max_msg_len = WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN;
|
||||
req_desc.msg_id = QMI_WLFW_WLAN_MODE_REQ_V01;
|
||||
req_desc.ei_array = wlfw_wlan_mode_req_msg_v01_ei;
|
||||
|
||||
resp_desc.max_msg_len = WLFW_WLAN_MODE_RESP_MSG_V01_MAX_MSG_LEN;
|
||||
resp_desc.msg_id = QMI_WLFW_WLAN_MODE_RESP_V01;
|
||||
resp_desc.ei_array = wlfw_wlan_mode_resp_msg_v01_ei;
|
||||
|
||||
ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req),
|
||||
&resp_desc, &resp, sizeof(resp),
|
||||
WLFW_TIMEOUT_MS);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: send req failed %d\n", __func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
pr_err("%s: QMI request failed %d %d\n",
|
||||
__func__, resp.resp.result, resp.resp.error);
|
||||
ret = resp.resp.result;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wlfw_wlan_cfg_send_sync_msg(struct wlfw_wlan_cfg_req_msg_v01 *data)
|
||||
{
|
||||
int ret;
|
||||
struct wlfw_wlan_cfg_req_msg_v01 req;
|
||||
struct wlfw_wlan_cfg_resp_msg_v01 resp;
|
||||
struct msg_desc req_desc, resp_desc;
|
||||
|
||||
if (!penv || !penv->wlfw_clnt) {
|
||||
return -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
|
||||
memcpy(&req, data, sizeof(req));
|
||||
|
||||
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;
|
||||
|
||||
resp_desc.max_msg_len = WLFW_WLAN_CFG_RESP_MSG_V01_MAX_MSG_LEN;
|
||||
resp_desc.msg_id = QMI_WLFW_WLAN_CFG_RESP_V01;
|
||||
resp_desc.ei_array = wlfw_wlan_cfg_resp_msg_v01_ei;
|
||||
|
||||
ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req),
|
||||
&resp_desc, &resp, sizeof(resp),
|
||||
WLFW_TIMEOUT_MS);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: send req failed %d\n", __func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
|
||||
pr_err("%s: QMI request failed %d %d\n",
|
||||
__func__, resp.resp.result, resp.resp.error);
|
||||
ret = resp.resp.result;
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void icnss_qmi_wlfw_clnt_notify_work(struct work_struct *work)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!penv || !penv->wlfw_clnt)
|
||||
return;
|
||||
|
||||
do {
|
||||
pr_debug("%s: Received Event\n", __func__);
|
||||
} while ((ret = qmi_recv_msg(penv->wlfw_clnt)) == 0);
|
||||
|
||||
if (ret != -ENOMSG)
|
||||
pr_err("%s: Error receiving message\n", __func__);
|
||||
}
|
||||
|
||||
static void icnss_qmi_wlfw_clnt_notify(struct qmi_handle *handle,
|
||||
enum qmi_event_type event, void *notify_priv)
|
||||
{
|
||||
if (!penv || !penv->wlfw_clnt)
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case QMI_RECV_MSG:
|
||||
schedule_work(&penv->qmi_recv_msg_work);
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: Received Event: %d\n", __func__, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle,
|
||||
unsigned int msg_id, void *msg,
|
||||
unsigned int msg_len, void *ind_cb_priv)
|
||||
{
|
||||
if (!penv)
|
||||
return;
|
||||
|
||||
pr_debug("%s: Received Ind 0x%x\n", __func__, msg_id);
|
||||
|
||||
switch (msg_id) {
|
||||
case QMI_WLFW_FW_READY_IND_V01:
|
||||
icnss_qmi_event_post(ICNSS_QMI_EVENT_FW_READY_IND, NULL);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Invalid msg_id 0x%x\n", __func__, msg_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int icnss_qmi_event_server_arrive(void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!penv)
|
||||
return -ENODEV;
|
||||
|
||||
penv->wlfw_clnt = qmi_handle_create(icnss_qmi_wlfw_clnt_notify, penv);
|
||||
if (!penv->wlfw_clnt) {
|
||||
pr_err("%s: QMI client handle alloc failed\n", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = qmi_connect_to_service(penv->wlfw_clnt,
|
||||
WLFW_SERVICE_ID_V01,
|
||||
WLFW_SERVICE_VERS_V01,
|
||||
WLFW_SERVICE_INS_ID_V01);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: Server not found : %d\n", __func__, ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = qmi_register_ind_cb(penv->wlfw_clnt,
|
||||
icnss_qmi_wlfw_clnt_ind, penv);
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to register indication callback: %d\n",
|
||||
ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
penv->state |= ICNSS_WLFW_QMI_CONNECTED;
|
||||
|
||||
pr_info("%s: QMI Server Connected\n", __func__);
|
||||
|
||||
ret = wlfw_ind_register_send_sync_msg();
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to send indication message: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wlfw_cap_send_sync_msg();
|
||||
if (ret < 0) {
|
||||
pr_err("Failed to get capability: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
return ret;
|
||||
fail:
|
||||
qmi_handle_destroy(penv->wlfw_clnt);
|
||||
penv->wlfw_clnt = NULL;
|
||||
out:
|
||||
ICNSS_ASSERT(0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int icnss_qmi_event_server_exit(void *data)
|
||||
{
|
||||
if (!penv || !penv->wlfw_clnt)
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("%s: QMI Service Disconnected\n", __func__);
|
||||
|
||||
qmi_handle_destroy(penv->wlfw_clnt);
|
||||
penv->state = 0;
|
||||
penv->wlfw_clnt = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icnss_qmi_event_fw_ready_ind(void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!penv)
|
||||
return -ENODEV;
|
||||
|
||||
penv->state |= ICNSS_FW_READY;
|
||||
|
||||
if (!penv->pdev) {
|
||||
pr_err("%s: Device is not ready\n", __func__);
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
if (!penv->ops || !penv->ops->probe) {
|
||||
pr_err("%s: WLAN driver is not registed yet\n", __func__);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = penv->ops->probe(&penv->pdev->dev);
|
||||
if (ret < 0)
|
||||
pr_err("%s: Driver probe failed: %d\n", __func__, ret);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int icnss_qmi_wlfw_clnt_svc_event_notify(struct notifier_block *this,
|
||||
unsigned long code,
|
||||
void *_cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!penv)
|
||||
return -ENODEV;
|
||||
|
||||
pr_debug("Event Notify: code: %ld", code);
|
||||
|
||||
switch (code) {
|
||||
case QMI_SERVER_ARRIVE:
|
||||
ret = icnss_qmi_event_post(ICNSS_QMI_EVENT_SERVER_ARRIVE, NULL);
|
||||
break;
|
||||
|
||||
case QMI_SERVER_EXIT:
|
||||
ret = icnss_qmi_event_post(ICNSS_QMI_EVENT_SERVER_EXIT, NULL);
|
||||
break;
|
||||
default:
|
||||
pr_debug("Invalid code: %ld", code);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void icnss_qmi_wlfw_event_work(struct work_struct *work)
|
||||
{
|
||||
struct icnss_qmi_event *event;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&penv->qmi_event_lock, flags);
|
||||
|
||||
while (!list_empty(&penv->qmi_event_list)) {
|
||||
event = list_first_entry(&penv->qmi_event_list,
|
||||
struct icnss_qmi_event, list);
|
||||
list_del(&event->list);
|
||||
spin_unlock_irqrestore(&penv->qmi_event_lock, flags);
|
||||
|
||||
switch (event->type) {
|
||||
case ICNSS_QMI_EVENT_SERVER_ARRIVE:
|
||||
icnss_qmi_event_server_arrive(event->data);
|
||||
break;
|
||||
case ICNSS_QMI_EVENT_SERVER_EXIT:
|
||||
icnss_qmi_event_server_exit(event->data);
|
||||
break;
|
||||
case ICNSS_QMI_EVENT_FW_READY_IND:
|
||||
icnss_qmi_event_fw_ready_ind(event->data);
|
||||
break;
|
||||
default:
|
||||
pr_debug("Invalid Event type: %d", event->type);
|
||||
break;
|
||||
}
|
||||
kfree(event);
|
||||
spin_lock_irqsave(&penv->qmi_event_lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&penv->qmi_event_lock, flags);
|
||||
}
|
||||
|
||||
static struct notifier_block wlfw_clnt_nb = {
|
||||
.notifier_call = icnss_qmi_wlfw_clnt_svc_event_notify,
|
||||
};
|
||||
|
||||
int icnss_register_driver(struct icnss_driver_ops *ops)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
int ret = 0;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pdev = penv->pdev;
|
||||
if (!pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (penv->ops) {
|
||||
pr_err("icnss: driver already registered\n");
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
penv->ops = ops;
|
||||
|
||||
/* check for all conditions before invoking probe */
|
||||
if (ICNSS_IS_FW_READY(penv->state) && penv->ops->probe)
|
||||
ret = penv->ops->probe(&pdev->dev);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_register_driver);
|
||||
|
||||
int icnss_unregister_driver(struct icnss_driver_ops *ops)
|
||||
{
|
||||
int ret = 0;
|
||||
struct platform_device *pdev;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pdev = penv->pdev;
|
||||
if (!pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
if (!penv->ops) {
|
||||
pr_err("icnss: driver not registered\n");
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
if (penv->ops->remove)
|
||||
penv->ops->remove(&pdev->dev);
|
||||
|
||||
penv->ops = NULL;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_unregister_driver);
|
||||
|
||||
int icnss_register_ce_irq(unsigned int ce_id,
|
||||
irqreturn_t (*handler)(int, void *),
|
||||
unsigned long flags, const char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int irq;
|
||||
struct ce_irq_list *irq_entry;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS) {
|
||||
pr_err("icnss: Invalid CE ID %d\n", ce_id);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
irq = penv->ce_irqs[ce_id];
|
||||
irq_entry = &penv->ce_irq_list[ce_id];
|
||||
|
||||
if (irq_entry->handler || irq_entry->irq) {
|
||||
pr_err("icnss: handler already registered %d\n", irq);
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = request_irq(irq, handler, IRQF_SHARED, name, &penv->pdev->dev);
|
||||
if (ret) {
|
||||
pr_err("icnss: IRQ not registered %d\n", irq);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
irq_entry->irq = irq;
|
||||
irq_entry->handler = handler;
|
||||
pr_debug("icnss: IRQ registered %d\n", irq);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_register_ce_irq);
|
||||
|
||||
int icnss_unregister_ce_irq(unsigned int ce_id)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int irq;
|
||||
struct ce_irq_list *irq_entry;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
irq = penv->ce_irqs[ce_id];
|
||||
irq_entry = &penv->ce_irq_list[ce_id];
|
||||
if (!irq_entry->handler || !irq_entry->irq) {
|
||||
pr_err("icnss: handler not registered %d\n", irq);
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
free_irq(irq, &penv->pdev->dev);
|
||||
irq_entry->irq = 0;
|
||||
irq_entry->handler = NULL;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_unregister_ce_irq);
|
||||
|
||||
int icnss_ce_request_irq(unsigned int ce_id,
|
||||
irqreturn_t (*handler)(int, void *),
|
||||
unsigned long flags, const char *name, void *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int irq;
|
||||
struct ce_irq_list *irq_entry;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
if (ce_id >= ICNSS_MAX_IRQ_REGISTRATIONS) {
|
||||
pr_err("icnss: Invalid CE ID %d\n", ce_id);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
irq = penv->ce_irqs[ce_id];
|
||||
irq_entry = &penv->ce_irq_list[ce_id];
|
||||
|
||||
if (irq_entry->handler || irq_entry->irq) {
|
||||
pr_err("icnss: handler already registered %d\n", irq);
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = request_irq(irq, handler, flags, name, ctx);
|
||||
if (ret) {
|
||||
pr_err("icnss: IRQ not registered %d\n", irq);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
irq_entry->irq = irq;
|
||||
irq_entry->handler = handler;
|
||||
pr_debug("icnss: IRQ registered %d\n", irq);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_ce_request_irq);
|
||||
|
||||
int icnss_ce_free_irq(unsigned int ce_id, void *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int irq;
|
||||
struct ce_irq_list *irq_entry;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
irq = penv->ce_irqs[ce_id];
|
||||
irq_entry = &penv->ce_irq_list[ce_id];
|
||||
if (!irq_entry->handler || !irq_entry->irq) {
|
||||
pr_err("icnss: handler not registered %d\n", irq);
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
free_irq(irq, ctx);
|
||||
irq_entry->irq = 0;
|
||||
irq_entry->handler = NULL;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_ce_free_irq);
|
||||
|
||||
void icnss_enable_irq(unsigned int ce_id)
|
||||
{
|
||||
unsigned int irq;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
pr_err("icnss: platform driver not initialized\n");
|
||||
return;
|
||||
}
|
||||
irq = penv->ce_irqs[ce_id];
|
||||
enable_irq(irq);
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_enable_irq);
|
||||
|
||||
void icnss_disable_irq(unsigned int ce_id)
|
||||
{
|
||||
unsigned int irq;
|
||||
|
||||
if (!penv || !penv->pdev) {
|
||||
pr_err("icnss: platform driver not initialized\n");
|
||||
return;
|
||||
}
|
||||
irq = penv->ce_irqs[ce_id];
|
||||
disable_irq(irq);
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_disable_irq);
|
||||
|
||||
int icnss_get_soc_info(struct icnss_soc_info *info)
|
||||
{
|
||||
if (!penv) {
|
||||
pr_err("icnss: platform driver not initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info->v_addr = penv->mem_base_va;
|
||||
info->p_addr = penv->mem_base_pa;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_get_soc_info);
|
||||
|
||||
int icnss_wlan_enable(struct icnss_wlan_enable_cfg *config,
|
||||
enum icnss_driver_mode mode,
|
||||
const char *host_version)
|
||||
{
|
||||
struct wlfw_wlan_cfg_req_msg_v01 req;
|
||||
u32 i;
|
||||
int ret;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
if (mode == ICNSS_WALTEST)
|
||||
goto skip;
|
||||
else if (!config || !host_version) {
|
||||
pr_err("%s: Invalid cfg pointer\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
req.host_version_valid = 1;
|
||||
strlcpy(req.host_version, host_version,
|
||||
QMI_WLFW_MAX_STR_LEN_V01 + 1);
|
||||
|
||||
req.tgt_cfg_valid = 1;
|
||||
if (config->num_ce_tgt_cfg > QMI_WLFW_MAX_NUM_CE_V01)
|
||||
req.tgt_cfg_len = QMI_WLFW_MAX_NUM_CE_V01;
|
||||
else
|
||||
req.tgt_cfg_len = config->num_ce_tgt_cfg;
|
||||
for (i = 0; i < req.tgt_cfg_len; i++) {
|
||||
req.tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num;
|
||||
req.tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir;
|
||||
req.tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries;
|
||||
req.tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max;
|
||||
req.tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags;
|
||||
}
|
||||
|
||||
req.svc_cfg_valid = 1;
|
||||
if (config->num_ce_svc_pipe_cfg > QMI_WLFW_MAX_NUM_SVC_V01)
|
||||
req.svc_cfg_len = QMI_WLFW_MAX_NUM_SVC_V01;
|
||||
else
|
||||
req.svc_cfg_len = config->num_ce_svc_pipe_cfg;
|
||||
for (i = 0; i < req.svc_cfg_len; i++) {
|
||||
req.svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id;
|
||||
req.svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir;
|
||||
req.svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
ret = wlfw_wlan_cfg_send_sync_msg(&req);
|
||||
if (ret) {
|
||||
pr_err("%s: Failed to send cfg, ret = %d\n", __func__, ret);
|
||||
goto out;
|
||||
}
|
||||
skip:
|
||||
ret = wlfw_wlan_mode_send_sync_msg(mode);
|
||||
if (ret)
|
||||
pr_err("%s: Failed to send mode, ret = %d\n", __func__, ret);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_wlan_enable);
|
||||
|
||||
int icnss_wlan_disable(enum icnss_driver_mode mode)
|
||||
{
|
||||
return wlfw_wlan_mode_send_sync_msg(QMI_WLFW_OFF_V01);
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_wlan_disable);
|
||||
|
||||
int icnss_get_ce_id(int irq)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ICNSS_MAX_IRQ_REGISTRATIONS; i++) {
|
||||
if (penv->ce_irqs[i] == irq)
|
||||
return i;
|
||||
}
|
||||
pr_err("icnss: No matching CE id for irq %d\n", irq);
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(icnss_get_ce_id);
|
||||
|
||||
static int icnss_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct resource *res;
|
||||
int i;
|
||||
|
||||
if (penv)
|
||||
return -EEXIST;
|
||||
|
||||
penv = devm_kzalloc(&pdev->dev, sizeof(*penv), GFP_KERNEL);
|
||||
if (!penv)
|
||||
return -ENOMEM;
|
||||
|
||||
penv->pdev = pdev;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase");
|
||||
if (!res) {
|
||||
pr_err("icnss: Memory base not found\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
penv->mem_base_pa = res->start;
|
||||
penv->mem_base_va = ioremap(penv->mem_base_pa, resource_size(res));
|
||||
if (!penv->mem_base_va) {
|
||||
pr_err("icnss: ioremap failed\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < ICNSS_MAX_IRQ_REGISTRATIONS; i++) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
|
||||
if (!res) {
|
||||
pr_err("icnss: Fail to get IRQ-%d\n", i);
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
} else {
|
||||
penv->ce_irqs[i] = res->start;
|
||||
}
|
||||
}
|
||||
|
||||
penv->qmi_event_wq = alloc_workqueue("icnss_qmi_event", 0, 0);
|
||||
if (!penv->qmi_event_wq) {
|
||||
pr_err("%s: workqueue creation failed\n", __func__);
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
INIT_WORK(&penv->qmi_event_work, icnss_qmi_wlfw_event_work);
|
||||
INIT_WORK(&penv->qmi_recv_msg_work, icnss_qmi_wlfw_clnt_notify_work);
|
||||
INIT_LIST_HEAD(&penv->qmi_event_list);
|
||||
|
||||
ret = qmi_svc_event_notifier_register(WLFW_SERVICE_ID_V01,
|
||||
WLFW_SERVICE_VERS_V01,
|
||||
WLFW_SERVICE_INS_ID_V01,
|
||||
&wlfw_clnt_nb);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: notifier register failed\n", __func__);
|
||||
destroy_workqueue(penv->qmi_event_wq);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pr_debug("icnss: Platform driver probed successfully\n");
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int icnss_remove(struct platform_device *pdev)
|
||||
{
|
||||
qmi_svc_event_notifier_unregister(WLFW_SERVICE_ID_V01,
|
||||
WLFW_SERVICE_VERS_V01,
|
||||
WLFW_SERVICE_INS_ID_V01,
|
||||
&wlfw_clnt_nb);
|
||||
if (penv->qmi_event_wq)
|
||||
destroy_workqueue(penv->qmi_event_wq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct of_device_id icnss_dt_match[] = {
|
||||
{.compatible = "qcom,icnss"},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, icnss_dt_match);
|
||||
|
||||
static struct platform_driver icnss_driver = {
|
||||
.probe = icnss_probe,
|
||||
.remove = icnss_remove,
|
||||
.driver = {
|
||||
.name = "icnss",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = icnss_dt_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init icnss_initialize(void)
|
||||
{
|
||||
return platform_driver_register(&icnss_driver);
|
||||
}
|
||||
|
||||
static void __exit icnss_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&icnss_driver);
|
||||
}
|
||||
|
||||
|
||||
module_init(icnss_initialize);
|
||||
module_exit(icnss_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION(DEVICE "iCNSS CORE platform driver");
|
978
drivers/soc/qcom/wlan_firmware_service_v01.c
Normal file
978
drivers/soc/qcom/wlan_firmware_service_v01.c
Normal file
|
@ -0,0 +1,978 @@
|
|||
/* Copyright (c) 2015, 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.
|
||||
*
|
||||
*/
|
||||
#include <linux/qmi_encdec.h>
|
||||
|
||||
#include <soc/qcom/msm_qmi_interface.h>
|
||||
|
||||
#include "wlan_firmware_service_v01.h"
|
||||
|
||||
static struct elem_info wlfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
|
||||
pipe_num),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_pipedir_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
|
||||
pipe_dir),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
|
||||
nentries),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
|
||||
nbytes_max),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_tgt_pipe_cfg_s_v01,
|
||||
flags),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct elem_info wlfw_ce_svc_pipe_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01,
|
||||
service_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_pipedir_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01,
|
||||
pipe_dir),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_ce_svc_pipe_cfg_s_v01,
|
||||
pipe_num),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct elem_info wlfw_shadow_reg_cfg_s_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_2_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint16_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_shadow_reg_cfg_s_v01,
|
||||
id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_2_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint16_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0,
|
||||
.offset = offsetof(struct wlfw_shadow_reg_cfg_s_v01,
|
||||
offset),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_ind_register_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
fw_ready_enable_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
fw_ready_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
initiate_cal_download_enable_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
initiate_cal_download_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
initiate_cal_update_enable_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_ind_register_req_msg_v01,
|
||||
initiate_cal_update_enable),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_ind_register_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_ind_register_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_fw_ready_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_wlan_mode_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_driver_mode_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_wlan_mode_req_msg_v01,
|
||||
mode),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_wlan_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_wlan_mode_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
host_version_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRING,
|
||||
.elem_len = QMI_WLFW_MAX_STR_LEN_V01 + 1,
|
||||
.elem_size = sizeof(char),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
host_version),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
tgt_cfg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
tgt_cfg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_CE_V01,
|
||||
.elem_size = sizeof(struct wlfw_ce_tgt_pipe_cfg_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
tgt_cfg),
|
||||
.ei_array = wlfw_ce_tgt_pipe_cfg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
svc_cfg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
svc_cfg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_SVC_V01,
|
||||
.elem_size = sizeof(struct wlfw_ce_svc_pipe_cfg_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
svc_cfg),
|
||||
.ei_array = wlfw_ce_svc_pipe_cfg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
shadow_reg_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
shadow_reg_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRUCT,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01,
|
||||
.elem_size = sizeof(struct wlfw_shadow_reg_cfg_s_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_wlan_cfg_req_msg_v01,
|
||||
shadow_reg),
|
||||
.ei_array = wlfw_shadow_reg_cfg_s_v01_ei,
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_wlan_cfg_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_wlan_cfg_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cap_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cap_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_cap_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
board_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
board_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
num_peers_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
num_peers),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
mac_version_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
mac_version),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
fw_version_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_STRING,
|
||||
.elem_len = QMI_WLFW_MAX_STR_LEN_V01 + 1,
|
||||
.elem_size = sizeof(char),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cap_resp_msg_v01,
|
||||
fw_version),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_bdf_download_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
file_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
file_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
total_size_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
seg_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
data_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint16_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
data_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = QMI_WLFW_MAX_DATA_SIZE_V01,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
data),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x14,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
end_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x14,
|
||||
.offset = offsetof(struct wlfw_bdf_download_req_msg_v01,
|
||||
end),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_bdf_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_bdf_download_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cal_report_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_cal_report_req_msg_v01,
|
||||
meta_data_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = QMI_WLFW_MAX_NUM_CAL_V01,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_cal_report_req_msg_v01,
|
||||
meta_data),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cal_report_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_cal_report_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_initiate_cal_download_ind_msg_v01,
|
||||
cal_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cal_download_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
file_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
file_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
total_size_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
seg_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
data_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint16_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
data_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = QMI_WLFW_MAX_DATA_SIZE_V01,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
data),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x14,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
end_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x14,
|
||||
.offset = offsetof(struct wlfw_cal_download_req_msg_v01,
|
||||
end),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cal_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_cal_download_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_initiate_cal_update_ind_msg_v01,
|
||||
cal_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct wlfw_initiate_cal_update_ind_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cal_update_req_msg_v01_ei[] = {
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x01,
|
||||
.offset = offsetof(struct wlfw_cal_update_req_msg_v01,
|
||||
cal_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x02,
|
||||
.offset = offsetof(struct wlfw_cal_update_req_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
struct elem_info wlfw_cal_update_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_cal_update_resp_msg_v01,
|
||||
resp),
|
||||
.ei_array = get_qmi_response_type_v01_ei(),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
file_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_SIGNED_4_BYTE_ENUM,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(enum wlfw_cal_temp_id_enum_v01),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x10,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
file_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
total_size_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x11,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
total_size),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
seg_id_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_4_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint32_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x12,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
seg_id),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
data_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_DATA_LEN,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint16_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
data_len),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = QMI_WLFW_MAX_DATA_SIZE_V01,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = VAR_LEN_ARRAY,
|
||||
.tlv_type = 0x13,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
data),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_OPT_FLAG,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x14,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
end_valid),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_UNSIGNED_1_BYTE,
|
||||
.elem_len = 1,
|
||||
.elem_size = sizeof(uint8_t),
|
||||
.is_array = NO_ARRAY,
|
||||
.tlv_type = 0x14,
|
||||
.offset = offsetof(struct wlfw_cal_update_resp_msg_v01,
|
||||
end),
|
||||
},
|
||||
{
|
||||
.data_type = QMI_EOTI,
|
||||
.is_array = NO_ARRAY,
|
||||
.is_array = QMI_COMMON_TLV_TYPE,
|
||||
},
|
||||
};
|
274
drivers/soc/qcom/wlan_firmware_service_v01.h
Normal file
274
drivers/soc/qcom/wlan_firmware_service_v01.h
Normal file
|
@ -0,0 +1,274 @@
|
|||
/* Copyright (c) 2015, 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 WLAN_FIRMWARE_SERVICE_V01_H
|
||||
#define WLAN_FIRMWARE_SERVICE_V01_H
|
||||
|
||||
#define WLFW_SERVICE_ID_V01 0x45
|
||||
#define WLFW_SERVICE_VERS_V01 0x01
|
||||
|
||||
#define QMI_WLFW_CAL_REPORT_REQ_V01 0x0026
|
||||
#define QMI_WLFW_CAL_REPORT_RESP_V01 0x0026
|
||||
#define QMI_WLFW_CAP_RESP_V01 0x0024
|
||||
#define QMI_WLFW_BDF_DOWNLOAD_REQ_V01 0x0025
|
||||
#define QMI_WLFW_CAL_DOWNLOAD_RESP_V01 0x0027
|
||||
#define QMI_WLFW_WLAN_MODE_RESP_V01 0x0022
|
||||
#define QMI_WLFW_CAL_UPDATE_RESP_V01 0x0029
|
||||
#define QMI_WLFW_BDF_DOWNLOAD_RESP_V01 0x0025
|
||||
#define QMI_WLFW_INITIATE_CAL_UPDATE_IND_V01 0x002A
|
||||
#define QMI_WLFW_FW_READY_IND_V01 0x0021
|
||||
#define QMI_WLFW_INITIATE_CAL_DOWNLOAD_IND_V01 0x0028
|
||||
#define QMI_WLFW_CAP_REQ_V01 0x0024
|
||||
#define QMI_WLFW_CAL_DOWNLOAD_REQ_V01 0x0027
|
||||
#define QMI_WLFW_WLAN_MODE_REQ_V01 0x0022
|
||||
#define QMI_WLFW_CAL_UPDATE_REQ_V01 0x0029
|
||||
#define QMI_WLFW_IND_REGISTER_REQ_V01 0x0020
|
||||
#define QMI_WLFW_WLAN_CFG_RESP_V01 0x0023
|
||||
#define QMI_WLFW_WLAN_CFG_REQ_V01 0x0023
|
||||
#define QMI_WLFW_IND_REGISTER_RESP_V01 0x0020
|
||||
|
||||
#define QMI_WLFW_MAX_NUM_CAL_V01 5
|
||||
#define QMI_WLFW_MAX_DATA_SIZE_V01 6144
|
||||
#define QMI_WLFW_MAX_NUM_CE_V01 12
|
||||
#define QMI_WLFW_MAX_STR_LEN_V01 16
|
||||
#define QMI_WLFW_MAX_NUM_SHADOW_REG_V01 24
|
||||
#define QMI_WLFW_MAX_NUM_SVC_V01 24
|
||||
|
||||
enum wlfw_driver_mode_enum_v01 {
|
||||
WLFW_DRIVER_MODE_ENUM_MIN_VAL_V01 = INT_MIN,
|
||||
QMI_WLFW_MISSION_V01 = 0,
|
||||
QMI_WLFW_FTM_V01 = 1,
|
||||
QMI_WLFW_EPPING_V01 = 2,
|
||||
QMI_WLFW_WALTEST_V01 = 3,
|
||||
QMI_WLFW_OFF_V01 = 4,
|
||||
WLFW_DRIVER_MODE_ENUM_MAX_VAL_V01 = INT_MAX,
|
||||
};
|
||||
|
||||
enum wlfw_cal_temp_id_enum_v01 {
|
||||
WLFW_CAL_TEMP_ID_ENUM_MIN_VAL_V01 = INT_MIN,
|
||||
QMI_WLFW_CAL_TEMP_IDX_0_V01 = 0,
|
||||
QMI_WLFW_CAL_TEMP_IDX_1_V01 = 1,
|
||||
QMI_WLFW_CAL_TEMP_IDX_2_V01 = 2,
|
||||
QMI_WLFW_CAL_TEMP_IDX_3_V01 = 3,
|
||||
QMI_WLFW_CAL_TEMP_IDX_4_V01 = 4,
|
||||
WLFW_CAL_TEMP_ID_ENUM_MAX_VAL_V01 = INT_MAX,
|
||||
};
|
||||
|
||||
enum wlfw_pipedir_enum_v01 {
|
||||
WLFW_PIPEDIR_ENUM_MIN_VAL_V01 = INT_MIN,
|
||||
QMI_WLFW_PIPEDIR_NONE_V01 = 0,
|
||||
QMI_WLFW_PIPEDIR_IN_V01 = 1,
|
||||
QMI_WLFW_PIPEDIR_OUT_V01 = 2,
|
||||
QMI_WLFW_PIPEDIR_INOUT_V01 = 3,
|
||||
WLFW_PIPEDIR_ENUM_MAX_VAL_V01 = INT_MAX,
|
||||
};
|
||||
|
||||
#define QMI_WLFW_CE_ATTR_FLAGS_V01 ((uint32_t)0x00)
|
||||
#define QMI_WLFW_CE_ATTR_NO_SNOOP_V01 ((uint32_t)0x01)
|
||||
#define QMI_WLFW_CE_ATTR_BYTE_SWAP_DATA_V01 ((uint32_t)0x02)
|
||||
#define QMI_WLFW_CE_ATTR_SWIZZLE_DESCRIPTORS_V01 ((uint32_t)0x04)
|
||||
#define QMI_WLFW_CE_ATTR_DISABLE_INTR_V01 ((uint32_t)0x08)
|
||||
#define QMI_WLFW_CE_ATTR_ENABLE_POLL_V01 ((uint32_t)0x10)
|
||||
|
||||
struct wlfw_ce_tgt_pipe_cfg_s_v01 {
|
||||
uint32_t pipe_num;
|
||||
enum wlfw_pipedir_enum_v01 pipe_dir;
|
||||
uint32_t nentries;
|
||||
uint32_t nbytes_max;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct wlfw_ce_svc_pipe_cfg_s_v01 {
|
||||
uint32_t service_id;
|
||||
enum wlfw_pipedir_enum_v01 pipe_dir;
|
||||
uint32_t pipe_num;
|
||||
};
|
||||
|
||||
struct wlfw_shadow_reg_cfg_s_v01 {
|
||||
uint16_t id;
|
||||
uint16_t offset;
|
||||
};
|
||||
|
||||
struct wlfw_ind_register_req_msg_v01 {
|
||||
uint8_t fw_ready_enable_valid;
|
||||
uint8_t fw_ready_enable;
|
||||
uint8_t initiate_cal_download_enable_valid;
|
||||
uint8_t initiate_cal_download_enable;
|
||||
uint8_t initiate_cal_update_enable_valid;
|
||||
uint8_t initiate_cal_update_enable;
|
||||
};
|
||||
#define WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN 12
|
||||
extern struct elem_info wlfw_ind_register_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_ind_register_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
#define WLFW_IND_REGISTER_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_ind_register_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_fw_ready_ind_msg_v01 {
|
||||
char placeholder;
|
||||
};
|
||||
#define WLFW_FW_READY_IND_MSG_V01_MAX_MSG_LEN 0
|
||||
extern struct elem_info wlfw_fw_ready_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_wlan_mode_req_msg_v01 {
|
||||
enum wlfw_driver_mode_enum_v01 mode;
|
||||
};
|
||||
#define WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_wlan_mode_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_wlan_mode_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
#define WLFW_WLAN_MODE_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_wlan_mode_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_wlan_cfg_req_msg_v01 {
|
||||
uint8_t host_version_valid;
|
||||
char host_version[QMI_WLFW_MAX_STR_LEN_V01 + 1];
|
||||
uint8_t tgt_cfg_valid;
|
||||
uint32_t tgt_cfg_len;
|
||||
struct wlfw_ce_tgt_pipe_cfg_s_v01 tgt_cfg[QMI_WLFW_MAX_NUM_CE_V01];
|
||||
uint8_t svc_cfg_valid;
|
||||
uint32_t svc_cfg_len;
|
||||
struct wlfw_ce_svc_pipe_cfg_s_v01 svc_cfg[QMI_WLFW_MAX_NUM_SVC_V01];
|
||||
uint8_t shadow_reg_valid;
|
||||
uint32_t shadow_reg_len;
|
||||
struct wlfw_shadow_reg_cfg_s_v01 shadow_reg[QMI_WLFW_MAX_NUM_SHADOW_REG_V01];
|
||||
};
|
||||
#define WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN 655
|
||||
extern struct elem_info wlfw_wlan_cfg_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_wlan_cfg_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
#define WLFW_WLAN_CFG_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_wlan_cfg_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cap_req_msg_v01 {
|
||||
char placeholder;
|
||||
};
|
||||
#define WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN 0
|
||||
extern struct elem_info wlfw_cap_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cap_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
uint8_t board_id_valid;
|
||||
uint32_t board_id;
|
||||
uint8_t num_peers_valid;
|
||||
uint32_t num_peers;
|
||||
uint8_t mac_version_valid;
|
||||
uint32_t mac_version;
|
||||
uint8_t fw_version_valid;
|
||||
char fw_version[QMI_WLFW_MAX_STR_LEN_V01 + 1];
|
||||
};
|
||||
#define WLFW_CAP_RESP_MSG_V01_MAX_MSG_LEN 47
|
||||
extern struct elem_info wlfw_cap_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_bdf_download_req_msg_v01 {
|
||||
uint8_t valid;
|
||||
uint8_t file_id_valid;
|
||||
enum wlfw_cal_temp_id_enum_v01 file_id;
|
||||
uint8_t total_size_valid;
|
||||
uint32_t total_size;
|
||||
uint8_t seg_id_valid;
|
||||
uint32_t seg_id;
|
||||
uint8_t data_valid;
|
||||
uint32_t data_len;
|
||||
uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01];
|
||||
uint8_t end_valid;
|
||||
uint8_t end;
|
||||
};
|
||||
#define WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6178
|
||||
extern struct elem_info wlfw_bdf_download_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_bdf_download_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
#define WLFW_BDF_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_bdf_download_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cal_report_req_msg_v01 {
|
||||
uint32_t meta_data_len;
|
||||
enum wlfw_cal_temp_id_enum_v01 meta_data[QMI_WLFW_MAX_NUM_CAL_V01];
|
||||
};
|
||||
#define WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN 24
|
||||
extern struct elem_info wlfw_cal_report_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cal_report_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
#define WLFW_CAL_REPORT_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_cal_report_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_initiate_cal_download_ind_msg_v01 {
|
||||
enum wlfw_cal_temp_id_enum_v01 cal_id;
|
||||
};
|
||||
#define WLFW_INITIATE_CAL_DOWNLOAD_IND_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_initiate_cal_download_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cal_download_req_msg_v01 {
|
||||
uint8_t valid;
|
||||
uint8_t file_id_valid;
|
||||
enum wlfw_cal_temp_id_enum_v01 file_id;
|
||||
uint8_t total_size_valid;
|
||||
uint32_t total_size;
|
||||
uint8_t seg_id_valid;
|
||||
uint32_t seg_id;
|
||||
uint8_t data_valid;
|
||||
uint32_t data_len;
|
||||
uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01];
|
||||
uint8_t end_valid;
|
||||
uint8_t end;
|
||||
};
|
||||
#define WLFW_CAL_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN 6178
|
||||
extern struct elem_info wlfw_cal_download_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cal_download_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
};
|
||||
#define WLFW_CAL_DOWNLOAD_RESP_MSG_V01_MAX_MSG_LEN 7
|
||||
extern struct elem_info wlfw_cal_download_resp_msg_v01_ei[];
|
||||
|
||||
struct wlfw_initiate_cal_update_ind_msg_v01 {
|
||||
enum wlfw_cal_temp_id_enum_v01 cal_id;
|
||||
uint32_t total_size;
|
||||
};
|
||||
#define WLFW_INITIATE_CAL_UPDATE_IND_MSG_V01_MAX_MSG_LEN 14
|
||||
extern struct elem_info wlfw_initiate_cal_update_ind_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cal_update_req_msg_v01 {
|
||||
enum wlfw_cal_temp_id_enum_v01 cal_id;
|
||||
uint32_t seg_id;
|
||||
};
|
||||
#define WLFW_CAL_UPDATE_REQ_MSG_V01_MAX_MSG_LEN 14
|
||||
extern struct elem_info wlfw_cal_update_req_msg_v01_ei[];
|
||||
|
||||
struct wlfw_cal_update_resp_msg_v01 {
|
||||
struct qmi_response_type_v01 resp;
|
||||
uint8_t file_id_valid;
|
||||
enum wlfw_cal_temp_id_enum_v01 file_id;
|
||||
uint8_t total_size_valid;
|
||||
uint32_t total_size;
|
||||
uint8_t seg_id_valid;
|
||||
uint32_t seg_id;
|
||||
uint8_t data_valid;
|
||||
uint32_t data_len;
|
||||
uint8_t data[QMI_WLFW_MAX_DATA_SIZE_V01];
|
||||
uint8_t end_valid;
|
||||
uint8_t end;
|
||||
};
|
||||
#define WLFW_CAL_UPDATE_RESP_MSG_V01_MAX_MSG_LEN 6181
|
||||
extern struct elem_info wlfw_cal_update_resp_msg_v01_ei[];
|
||||
|
||||
#endif
|
95
include/soc/qcom/icnss.h
Normal file
95
include/soc/qcom/icnss.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* Copyright (c) 2015, 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 _ICNSS_WLAN_H_
|
||||
#define _ICNSS_WLAN_H_
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#define ICNSS_MAX_IRQ_REGISTRATIONS 12
|
||||
|
||||
struct icnss_driver_ops {
|
||||
char *name;
|
||||
int (*probe)(struct device *dev);
|
||||
void (*remove)(struct device *dev);
|
||||
void (*shutdown)(struct device *dev);
|
||||
int (*reinit)(struct device *dev);
|
||||
void (*crash_shutdown)(void *pdev);
|
||||
int (*suspend)(struct device *dev, pm_message_t state);
|
||||
int (*resume)(struct device *dev);
|
||||
};
|
||||
|
||||
|
||||
struct ce_tgt_pipe_cfg {
|
||||
u32 pipe_num;
|
||||
u32 pipe_dir;
|
||||
u32 nentries;
|
||||
u32 nbytes_max;
|
||||
u32 flags;
|
||||
u32 reserved;
|
||||
};
|
||||
|
||||
struct ce_svc_pipe_cfg {
|
||||
u32 service_id;
|
||||
u32 pipe_dir;
|
||||
u32 pipe_num;
|
||||
};
|
||||
|
||||
struct icnss_shadow_reg_cfg {
|
||||
u16 ce_id;
|
||||
u16 reg_offset;
|
||||
};
|
||||
|
||||
/* CE configuration to target */
|
||||
struct icnss_wlan_enable_cfg {
|
||||
u32 num_ce_tgt_cfg;
|
||||
struct ce_tgt_pipe_cfg *ce_tgt_cfg;
|
||||
u32 num_ce_svc_pipe_cfg;
|
||||
struct ce_svc_pipe_cfg *ce_svc_cfg;
|
||||
u32 num_shadow_reg_cfg;
|
||||
struct icnss_shadow_reg_cfg *shadow_reg_cfg;
|
||||
};
|
||||
|
||||
/* driver modes */
|
||||
enum icnss_driver_mode {
|
||||
ICNSS_MISSION,
|
||||
ICNSS_FTM,
|
||||
ICNSS_EPPING,
|
||||
ICNSS_WALTEST,
|
||||
ICNSS_OFF,
|
||||
};
|
||||
|
||||
struct icnss_soc_info {
|
||||
void __iomem *v_addr;
|
||||
phys_addr_t p_addr;
|
||||
u32 version;
|
||||
};
|
||||
|
||||
extern int icnss_register_driver(struct icnss_driver_ops *driver);
|
||||
extern int icnss_unregister_driver(struct icnss_driver_ops *driver);
|
||||
extern int icnss_register_ce_irq(unsigned int ce_id,
|
||||
irqreturn_t (*handler)(int, void *),
|
||||
unsigned long flags, const char *name);
|
||||
extern int icnss_unregister_ce_irq(unsigned int ce_id);
|
||||
extern int icnss_wlan_enable(struct icnss_wlan_enable_cfg *config,
|
||||
enum icnss_driver_mode mode,
|
||||
const char *host_version);
|
||||
extern int icnss_wlan_disable(enum icnss_driver_mode mode);
|
||||
extern void icnss_enable_irq(unsigned int ce_id);
|
||||
extern void icnss_disable_irq(unsigned int ce_id);
|
||||
extern int icnss_get_soc_info(struct icnss_soc_info *info);
|
||||
extern int icnss_ce_free_irq(unsigned int ce_id, void *ctx);
|
||||
extern int icnss_ce_request_irq(unsigned int ce_id,
|
||||
irqreturn_t (*handler)(int, void *),
|
||||
unsigned long flags, const char *name, void *ctx);
|
||||
extern int icnss_get_ce_id(int irq);
|
||||
|
||||
#endif /* _ICNSS_WLAN_H_ */
|
Loading…
Add table
Reference in a new issue