Loading drivers/soc/qcom/dfc_qmi.c +180 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); } drivers/soc/qcom/qmi_rmnet.c +17 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; } Loading drivers/soc/qcom/qmi_rmnet_i.h +8 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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 Loading Loading
drivers/soc/qcom/dfc_qmi.c +180 −2 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); }
drivers/soc/qcom/qmi_rmnet.c +17 −1 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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; } Loading
drivers/soc/qcom/qmi_rmnet_i.h +8 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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 Loading