Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 001a4e2a authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: dfc: add query after existing powersave mode"

parents a2d442fe 8f006a33
Loading
Loading
Loading
Loading
+180 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@

#define DFC_IS_ANCILLARY(type) ((type) != AF_INET && (type) != AF_INET6)

#define DFC_MAX_BEARERS_V01 16
#define DFC_MAX_QOS_ID_V01 2

#define DFC_ACK_TYPE_DISABLE 1
@@ -86,6 +85,11 @@ static void dfc_svc_init(struct work_struct *work);
#define QMI_DFC_FLOW_STATUS_IND_V01 0x0022
#define QMI_DFC_FLOW_STATUS_IND_V01_MAX_MSG_LEN 540

#define QMI_DFC_GET_FLOW_STATUS_REQ_V01 0x0023
#define QMI_DFC_GET_FLOW_STATUS_RESP_V01 0x0023
#define QMI_DFC_GET_FLOW_STATUS_REQ_V01_MAX_MSG_LEN 20
#define QMI_DFC_GET_FLOW_STATUS_RESP_V01_MAX_MSG_LEN 543

struct dfc_bind_client_req_msg_v01 {
	u8 ep_id_valid;
	struct data_ep_id_type_v01 ep_id;
@@ -309,6 +313,19 @@ struct dfc_flow_status_ind_msg_v01 {
	struct dfc_ancillary_info_type_v01 ancillary_info[DFC_MAX_BEARERS_V01];
};

struct dfc_get_flow_status_req_msg_v01 {
	u8 bearer_id_list_valid;
	u8 bearer_id_list_len;
	u8 bearer_id_list[DFC_MAX_BEARERS_V01];
};

struct dfc_get_flow_status_resp_msg_v01 {
	struct qmi_response_type_v01 resp;
	u8 flow_status_valid;
	u8 flow_status_len;
	struct dfc_flow_status_info_type_v01 flow_status[DFC_MAX_BEARERS_V01];
};

struct dfc_svc_ind {
	struct list_head list;
	struct dfc_flow_status_ind_msg_v01 dfc_info;
@@ -507,6 +524,100 @@ static struct qmi_elem_info dfc_flow_status_ind_v01_ei[] = {
	},
};

static struct qmi_elem_info dfc_get_flow_status_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
					   dfc_get_flow_status_req_msg_v01,
					   bearer_id_list_valid),
		.ei_array	= NULL,
	},
	{
		.data_type	= QMI_DATA_LEN,
		.elem_len	= 1,
		.elem_size	= sizeof(u8),
		.is_array	= NO_ARRAY,
		.tlv_type	= 0x10,
		.offset		= offsetof(struct
					   dfc_get_flow_status_req_msg_v01,
					   bearer_id_list_len),
		.ei_array	= NULL,
	},
	{
		.data_type	= QMI_UNSIGNED_1_BYTE,
		.elem_len	= DFC_MAX_BEARERS_V01,
		.elem_size	= sizeof(u8),
		.is_array	= VAR_LEN_ARRAY,
		.tlv_type	= 0x10,
		.offset		= offsetof(struct
					   dfc_get_flow_status_req_msg_v01,
					   bearer_id_list),
		.ei_array	= NULL,
	},
	{
		.data_type	= QMI_EOTI,
		.is_array	= NO_ARRAY,
		.tlv_type	= QMI_COMMON_TLV_TYPE,
	},
};

static struct qmi_elem_info dfc_get_flow_status_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
					   dfc_get_flow_status_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
					   dfc_get_flow_status_resp_msg_v01,
					   flow_status_valid),
		.ei_array	= NULL,
	},
	{
		.data_type	= QMI_DATA_LEN,
		.elem_len	= 1,
		.elem_size	= sizeof(u8),
		.is_array	= NO_ARRAY,
		.tlv_type	= 0x10,
		.offset		= offsetof(struct
					   dfc_get_flow_status_resp_msg_v01,
					   flow_status_len),
		.ei_array	= NULL,
	},
	{
		.data_type	= QMI_STRUCT,
		.elem_len	= DFC_MAX_BEARERS_V01,
		.elem_size	= sizeof(struct
					 dfc_get_flow_status_resp_msg_v01),
		.is_array	= VAR_LEN_ARRAY,
		.tlv_type	= 0x10,
		.offset		= offsetof(struct
					   dfc_get_flow_status_resp_msg_v01,
					   flow_status),
		.ei_array	= dfc_flow_status_info_type_v01_ei,
	},
	{
		.data_type	= QMI_EOTI,
		.is_array	= NO_ARRAY,
		.tlv_type	= QMI_COMMON_TLV_TYPE,
	},
};

static int
dfc_bind_client_req(struct qmi_handle *dfc_handle,
		    struct sockaddr_qrtr *ssctl, struct svc_info *svc)
@@ -620,6 +731,49 @@ dfc_indication_register_req(struct qmi_handle *dfc_handle,
	return ret;
}

static int
dfc_get_flow_status_req(struct qmi_handle *dfc_handle,
			struct sockaddr_qrtr *ssctl,
			struct dfc_get_flow_status_resp_msg_v01 *resp)
{
	struct dfc_get_flow_status_req_msg_v01 req;
	struct qmi_txn txn;
	int ret;

	ret = qmi_txn_init(dfc_handle, &txn,
			   dfc_get_flow_status_resp_msg_v01_ei, resp);
	if (ret < 0) {
		pr_err("%s() Failed init for response, err: %d\n",
			__func__, ret);
		goto out;
	}

	memset(&req, 0, sizeof(req));
	ret = qmi_send_request(dfc_handle, ssctl, &txn,
			       QMI_DFC_GET_FLOW_STATUS_REQ_V01,
			       QMI_DFC_GET_FLOW_STATUS_REQ_V01_MAX_MSG_LEN,
			       dfc_get_flow_status_req_msg_v01_ei, &req);
	if (ret < 0) {
		qmi_txn_cancel(&txn);
		pr_err("%s() Failed sending request, err: %d\n",
			__func__, ret);
		goto out;
	}

	ret = qmi_txn_wait(&txn, DFC_TIMEOUT_MS);
	if (ret < 0) {
		pr_err("%s() Response waiting failed, err: %d\n",
			__func__, ret);
	} else if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
		pr_err("%s() Request rejected, result: %d, err: %d\n",
			__func__, resp->resp.result, resp->resp.error);
		ret = -resp->resp.result;
	}

out:
	return ret;
}

static int dfc_init_service(struct dfc_qmi_data *data)
{
	int rc;
@@ -1000,7 +1154,7 @@ int dfc_qmi_client_init(void *port, int index, struct svc_info *psvc)

	INIT_WORK(&data->svc_arrive, dfc_svc_init);
	rc = qmi_handle_init(&data->handle,
			     QMI_DFC_FLOW_STATUS_IND_V01_MAX_MSG_LEN,
			     QMI_DFC_GET_FLOW_STATUS_RESP_V01_MAX_MSG_LEN,
			     &server_ops, qmi_indication_handler);
	if (rc < 0) {
		pr_err("%s: failed qmi_handle_init - rc[%d]\n", __func__, rc);
@@ -1098,3 +1252,27 @@ void dfc_qmi_wq_flush(struct qmi_info *qmi)
			flush_workqueue(dfc_data->dfc_wq);
	}
}

void dfc_qmi_query_flow(void *dfc_data)
{
	struct dfc_qmi_data *data = (struct dfc_qmi_data *)dfc_data;
	struct dfc_get_flow_status_resp_msg_v01 resp;
	struct dfc_svc_ind svc_ind;
	int rc;

	if (!data)
		return;

	rc = dfc_get_flow_status_req(&data->handle, &data->ssctl, &resp);

	if (rc < 0 || !resp.flow_status_valid || resp.flow_status_len < 1 ||
	    resp.flow_status_len > DFC_MAX_BEARERS_V01)
		return;

	memset(&svc_ind, 0, sizeof(svc_ind));
	svc_ind.dfc_info.flow_status_valid = resp.flow_status_valid;
	svc_ind.dfc_info.flow_status_len = resp.flow_status_len;
	memcpy(svc_ind.dfc_info.flow_status, resp.flow_status,
		sizeof(resp.flow_status[0]) * resp.flow_status_len);
	dfc_do_burst_flow_control(data, &svc_ind);
}
+17 −1
Original line number Diff line number Diff line
@@ -309,6 +309,16 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm,
	return 0;
}

static void qmi_rmnet_query_flows(struct qmi_info *qmi)
{
	void *dfc_data = qmi_rmnet_has_dfc_client(qmi);

	if (!dfc_data)
		return;

	dfc_qmi_query_flow(dfc_data);
}

static int qmi_rmnet_set_scale_factor(const char *val,
				      const struct kernel_param *kp)
{
@@ -359,6 +369,10 @@ qmi_rmnet_del_flow(struct net_device *dev, struct tcmsg *tcm,
{
	return -EINVAL;
}

static inline void qmi_rmnet_query_flows(struct qmi_info *qmi)
{
}
#endif

static int
@@ -533,7 +547,7 @@ void qmi_rmnet_enable_all_flows(struct net_device *dev)
		bearer->grant_before_ps = bearer->grant_size;
		bearer->seq_before_ps = bearer->seq;
		bearer->grant_size = DEFAULT_GRANT;
		bearer->grant_thresh = qmi_rmnet_grant_per(DEFAULT_GRANT);
		bearer->grant_thresh = DEFAULT_GRANT;
		bearer->seq = 0;
		bearer->ack_req = 0;
		bearer->ancillary = 0;
@@ -737,6 +751,8 @@ int qmi_rmnet_set_powersave_mode(void *port, uint8_t enable)

	if (enable)
		dfc_qmi_wq_flush(qmi);
	else
		qmi_rmnet_query_flows(qmi);

	return 0;
}
+8 −1
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@

#define MAX_CLIENT_NUM 2
#define MAX_FLOW_NUM 32
#define DEFAULT_GRANT 10240
#define DEFAULT_GRANT 1
#define DFC_MAX_BEARERS_V01 16

struct rmnet_flow_map {
	struct list_head list;
@@ -115,6 +116,7 @@ int qmi_rmnet_flow_control(struct net_device *dev, u32 tcm_handle, int enable);

void dfc_qmi_wq_flush(struct qmi_info *qmi);

void dfc_qmi_query_flow(void *dfc_data);
#else
static inline struct rmnet_flow_map *
qmi_rmnet_get_flow_map(struct qos_info *qos_info,
@@ -149,6 +151,11 @@ static inline void
dfc_qmi_wq_flush(struct qmi_info *qmi)
{
}

static inline void
dfc_qmi_query_flow(void *dfc_data)
{
}
#endif

#ifdef CONFIG_QCOM_QMI_POWER_COLLAPSE