Loading drivers/platform/msm/ipa/ipa_qmi_service.c +28 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ static bool qmi_modem_init_fin, qmi_indication_fin; static struct work_struct ipa_qmi_service_init_work; static bool is_load_uc; static uint32_t ipa_wan_platform; struct ipa_qmi_context *ipa_qmi_ctx; /* QMI A5 service */ Loading Loading @@ -453,6 +453,13 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) req->filter_spec_list_len); } /* cache the qmi_filter_request */ memcpy(&(ipa_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[ ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg]), req, sizeof(struct ipa_install_fltr_rule_req_msg_v01)); ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg++; ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10; req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01; req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01; req_desc.ei_array = ipa_install_fltr_rule_req_msg_data_v01_ei; Loading Loading @@ -498,6 +505,14 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req) req->filter_index_list[i].filter_index); return -EINVAL; } /* cache the qmi_filter_request */ memcpy(&(ipa_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[ ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]), req, sizeof(struct ipa_fltr_installed_notif_req_msg_v01)); ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++; ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10; req_desc.max_msg_len = QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01; req_desc.msg_id = QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01; Loading Loading @@ -650,6 +665,13 @@ static void ipa_qmi_service_init_worker(struct work_struct *work) /* Initialize QMI-service*/ IPAWANDBG("IPA A7 QMI init OK :>>>>\n"); /* start the QMI msg cache */ ipa_qmi_ctx = kzalloc(sizeof(*ipa_qmi_ctx), GFP_KERNEL); if (!ipa_qmi_ctx) { IPAWANERR(":kzalloc err.\n"); return; } ipa_svc_workqueue = create_singlethread_workqueue("ipa_A7_svc"); if (!ipa_svc_workqueue) { IPAWANERR("Creating ipa_A7_svc workqueue failed\n"); Loading Loading @@ -780,6 +802,11 @@ void ipa_qmi_service_exit(void) ipa_clnt_resp_workqueue = NULL; } /* clean the QMI msg cache */ if (ipa_qmi_ctx != NULL) { kfree(ipa_qmi_ctx); ipa_qmi_ctx = NULL; } ipa_svc_handle = 0; qmi_modem_init_fin = false; qmi_indication_fin = false; Loading drivers/platform/msm/ipa/ipa_qmi_service.h +15 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-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 Loading @@ -25,6 +25,7 @@ #define IPA_A7_QMAP_HDR_NAME "ipa_qmap_hdr" #define IPA_DFLT_WAN_RT_TBL_NAME "ipa_dflt_wan_rt" #define MAX_NUM_Q6_RULE 35 #define MAX_NUM_QMI_RULE_CACHE 10 #define DEV_NAME "ipa-wan" #define SUBSYS_MODEM "modem" Loading @@ -33,6 +34,19 @@ #define IPAWANERR(fmt, args...) \ pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) extern struct ipa_qmi_context *ipa_qmi_ctx; struct ipa_qmi_context { struct ipa_ioc_ext_intf_prop q6_ul_filter_rule[MAX_NUM_Q6_RULE]; u32 q6_ul_filter_rule_hdl[MAX_NUM_Q6_RULE]; int num_ipa_install_fltr_rule_req_msg; struct ipa_install_fltr_rule_req_msg_v01 ipa_install_fltr_rule_req_msg_cache[MAX_NUM_QMI_RULE_CACHE]; int num_ipa_fltr_installed_notif_req_msg; struct ipa_fltr_installed_notif_req_msg_v01 ipa_fltr_installed_notif_req_msg_cache[MAX_NUM_QMI_RULE_CACHE]; }; struct rmnet_mux_val { uint32_t mux_id; int8_t vchannel_name[IFNAMSIZ]; Loading drivers/platform/msm/ipa/rmnet_ipa.c +118 −112 Original line number Diff line number Diff line Loading @@ -48,8 +48,6 @@ static struct net_device *ipa_netdevs[IPA_WWAN_DEVICE_COUNT]; static struct ipa_sys_connect_params apps_to_ipa_ep_cfg, ipa_to_apps_ep_cfg; static u32 qmap_hdr_hdl, dflt_v4_wan_rt_hdl, dflt_v6_wan_rt_hdl; static struct ipa_ioc_ext_intf_prop q6_ul_filter_rule[MAX_NUM_Q6_RULE]; static u32 q6_ul_filter_rule_hdl[MAX_NUM_Q6_RULE]; static struct rmnet_mux_val mux_channel[MAX_NUM_OF_MUX_CHANNEL]; static int num_q6_rule, old_num_q6_rule; static int rmnet_index; Loading Loading @@ -395,143 +393,150 @@ int copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01 break; } /* construct UL_filter_rule handler QMI use-cas */ q6_ul_filter_rule[i].filter_hdl = ipa_qmi_ctx->q6_ul_filter_rule[i].filter_hdl = UL_FILTER_RULE_HANDLE_START + i; rule_hdl[i] = q6_ul_filter_rule[i].filter_hdl; q6_ul_filter_rule[i].ip = rule_req->filter_spec_list[i].ip_type; q6_ul_filter_rule[i].action = rule_hdl[i] = ipa_qmi_ctx->q6_ul_filter_rule[i].filter_hdl; ipa_qmi_ctx->q6_ul_filter_rule[i].ip = rule_req->filter_spec_list[i].ip_type; ipa_qmi_ctx->q6_ul_filter_rule[i].action = rule_req->filter_spec_list[i].filter_action; if (rule_req->filter_spec_list[i].is_routing_table_index_valid == true) q6_ul_filter_rule[i].rt_tbl_idx = ipa_qmi_ctx->q6_ul_filter_rule[i].rt_tbl_idx = rule_req->filter_spec_list[i].route_table_index; if (rule_req->filter_spec_list[i].is_mux_id_valid == true) q6_ul_filter_rule[i].mux_id = ipa_qmi_ctx->q6_ul_filter_rule[i].mux_id = rule_req->filter_spec_list[i].mux_id; q6_ul_filter_rule[i].eq_attrib.rule_eq_bitmap = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.rule_eq_bitmap = rule_req->filter_spec_list[i].filter_rule. rule_eq_bitmap; q6_ul_filter_rule[i].eq_attrib.tos_eq_present = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tos_eq_present = rule_req->filter_spec_list[i].filter_rule. tos_eq_present; q6_ul_filter_rule[i].eq_attrib.tos_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tos_eq = rule_req->filter_spec_list[i].filter_rule.tos_eq; q6_ul_filter_rule[i].eq_attrib.protocol_eq_present = rule_req->filter_spec_list[i].filter_rule. protocol_eq_present; q6_ul_filter_rule[i].eq_attrib.protocol_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. protocol_eq_present = rule_req->filter_spec_list[i]. filter_rule.protocol_eq_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.protocol_eq = rule_req->filter_spec_list[i].filter_rule. protocol_eq; q6_ul_filter_rule[i].eq_attrib.num_ihl_offset_range_16 = rule_req->filter_spec_list[i].filter_rule. num_ihl_offset_range_16; for (j = 0; j < q6_ul_filter_rule[i].eq_attrib. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_ihl_offset_range_16 = rule_req->filter_spec_list[i]. filter_rule.num_ihl_offset_range_16; for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_ihl_offset_range_16; j++) { q6_ul_filter_rule[i].eq_attrib.ihl_offset_range_16[j]. offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_range_16[j].offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_range_16[j]. range_low = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_range_16[j].range_low; q6_ul_filter_rule[i].eq_attrib.ihl_offset_range_16[j]. range_high = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_range_16[j].range_high; } q6_ul_filter_rule[i].eq_attrib.num_offset_meq_32 = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_range_16[j].offset = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_range_16[j].offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_range_16[j].range_low = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_range_16[j].range_low; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_range_16[j].range_high = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_range_16[j].range_high; } ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.num_offset_meq_32 = rule_req->filter_spec_list[i].filter_rule. num_offset_meq_32; for (j = 0; j < q6_ul_filter_rule[i].eq_attrib. for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_offset_meq_32; j++) { q6_ul_filter_rule[i].eq_attrib.offset_meq_32[j].offset = rule_req->filter_spec_list[i].filter_rule. offset_meq_32[j].offset; q6_ul_filter_rule[i].eq_attrib.offset_meq_32[j].mask = rule_req->filter_spec_list[i].filter_rule. offset_meq_32[j].mask; q6_ul_filter_rule[i].eq_attrib.offset_meq_32[j].value = rule_req->filter_spec_list[i].filter_rule. offset_meq_32[j].value; } q6_ul_filter_rule[i].eq_attrib.tc_eq_present = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_32[j].offset = rule_req->filter_spec_list[i]. filter_rule.offset_meq_32[j].offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_32[j].mask = rule_req->filter_spec_list[i]. filter_rule.offset_meq_32[j].mask; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_32[j].value = rule_req->filter_spec_list[i]. filter_rule.offset_meq_32[j].value; } ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tc_eq_present = rule_req->filter_spec_list[i].filter_rule.tc_eq_present; q6_ul_filter_rule[i].eq_attrib.tc_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tc_eq = rule_req->filter_spec_list[i].filter_rule.tc_eq; q6_ul_filter_rule[i].eq_attrib.fl_eq_present = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.fl_eq_present = rule_req->filter_spec_list[i].filter_rule. flow_eq_present; q6_ul_filter_rule[i].eq_attrib.fl_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.fl_eq = rule_req->filter_spec_list[i].filter_rule.flow_eq; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_16_present = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_16_present; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_16.offset = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_16.offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_16.value = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_16.value; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_32_present = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_32_present; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_32.offset = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_32.offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_32.value = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_32.value; q6_ul_filter_rule[i].eq_attrib.num_ihl_offset_meq_32 = rule_req->filter_spec_list[i].filter_rule. num_ihl_offset_meq_32; for (j = 0; j < q6_ul_filter_rule[i]. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_16_present = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_16_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_16.offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_16.offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_16.value = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_16.value; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_32_present = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_32_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_32.offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_32.offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_32.value = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_32.value; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_ihl_offset_meq_32 = rule_req->filter_spec_list[i]. filter_rule.num_ihl_offset_meq_32; for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i]. eq_attrib.num_ihl_offset_meq_32; j++) { q6_ul_filter_rule[i].eq_attrib.ihl_offset_meq_32[j]. offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_meq_32[j].offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_meq_32[j]. mask = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_meq_32[j].mask; q6_ul_filter_rule[i].eq_attrib.ihl_offset_meq_32[j]. value = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_meq_32[j].value; } q6_ul_filter_rule[i].eq_attrib.num_offset_meq_128 = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_meq_32[j].offset = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_meq_32[j].offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_meq_32[j].mask = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_meq_32[j].mask; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_meq_32[j].value = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_meq_32[j].value; } ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.num_offset_meq_128 = rule_req->filter_spec_list[i].filter_rule. num_offset_meq_128; for (j = 0; j < q6_ul_filter_rule[i].eq_attrib. for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_offset_meq_128; j++) { q6_ul_filter_rule[i].eq_attrib.offset_meq_128[j]. offset = rule_req->filter_spec_list[i]. filter_rule.offset_meq_128[j].offset; memcpy(q6_ul_filter_rule[i].eq_attrib. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_128[j].offset = rule_req-> filter_spec_list[i].filter_rule. offset_meq_128[j].offset; memcpy(ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_128[j].mask, rule_req->filter_spec_list[i]. filter_rule.offset_meq_128[j].mask, 16); memcpy(q6_ul_filter_rule[i].eq_attrib.offset_meq_128[j]. value, rule_req->filter_spec_list[i]. filter_rule.offset_meq_128[j].value, 16); filter_rule.offset_meq_128[j].mask, 16); memcpy(ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_128[j].value, rule_req-> filter_spec_list[i].filter_rule. offset_meq_128[j].value, 16); } q6_ul_filter_rule[i].eq_attrib.metadata_meq32_present = rule_req->filter_spec_list[i]. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. metadata_meq32_present = rule_req->filter_spec_list[i]. filter_rule.metadata_meq32_present; q6_ul_filter_rule[i].eq_attrib.metadata_meq32.offset = rule_req->filter_spec_list[i].filter_rule. metadata_meq32.offset; q6_ul_filter_rule[i].eq_attrib.metadata_meq32.mask = rule_req->filter_spec_list[i].filter_rule. metadata_meq32.mask; q6_ul_filter_rule[i].eq_attrib.metadata_meq32.value = rule_req->filter_spec_list[i].filter_rule. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. metadata_meq32.offset = rule_req->filter_spec_list[i]. filter_rule.metadata_meq32.offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. metadata_meq32.mask = rule_req->filter_spec_list[i]. filter_rule.metadata_meq32.mask; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.metadata_meq32. value = rule_req->filter_spec_list[i].filter_rule. metadata_meq32.value; q6_ul_filter_rule[i].eq_attrib.ipv4_frag_eq_present = rule_req->filter_spec_list[i].filter_rule. ipv4_frag_eq_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ipv4_frag_eq_present = rule_req->filter_spec_list[i]. filter_rule.ipv4_frag_eq_present; } return rc; } Loading @@ -557,12 +562,13 @@ static int wwan_add_ul_flt_rule_to_ipa(void) param->num_rules = (uint8_t)1; for (i = 0; i < num_q6_rule; i++) { param->ip = q6_ul_filter_rule[i].ip; param->ip = ipa_qmi_ctx->q6_ul_filter_rule[i].ip; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = q6_ul_filter_rule[i].action; flt_rule_entry.rule.action = ipa_qmi_ctx->q6_ul_filter_rule[i].action; flt_rule_entry.rule.rt_tbl_idx = q6_ul_filter_rule[i].rt_tbl_idx; = ipa_qmi_ctx->q6_ul_filter_rule[i].rt_tbl_idx; flt_rule_entry.rule.retain_hdr = true; /* debug rt-hdl*/ Loading @@ -570,7 +576,7 @@ static int wwan_add_ul_flt_rule_to_ipa(void) i, flt_rule_entry.rule.rt_tbl_idx); flt_rule_entry.rule.eq_attrib_type = true; memcpy(&(flt_rule_entry.rule.eq_attrib), &q6_ul_filter_rule[i].eq_attrib, &ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib, sizeof(struct ipa_ipfltri_rule_eq)); memcpy(&(param->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); Loading @@ -579,7 +585,8 @@ static int wwan_add_ul_flt_rule_to_ipa(void) IPAWANERR("add A7 UL filter rule(%d) failed\n", i); } else { /* store the rule handler */ q6_ul_filter_rule_hdl[i] = param->rules[0].flt_rule_hdl; ipa_qmi_ctx->q6_ul_filter_rule_hdl[i] = param->rules[0].flt_rule_hdl; } } Loading @@ -590,7 +597,7 @@ static int wwan_add_ul_flt_rule_to_ipa(void) req.install_status = QMI_RESULT_SUCCESS_V01; req.filter_index_list_len = num_q6_rule; for (i = 0; i < num_q6_rule; i++) { if (q6_ul_filter_rule[i].ip == IPA_IP_v4) { if (ipa_qmi_ctx->q6_ul_filter_rule[i].ip == IPA_IP_v4) { req.filter_index_list[i].filter_index = num_v4_rule; num_v4_rule++; } else { Loading @@ -598,7 +605,7 @@ static int wwan_add_ul_flt_rule_to_ipa(void) num_v6_rule++; } req.filter_index_list[i].filter_handle = q6_ul_filter_rule[i].filter_hdl; ipa_qmi_ctx->q6_ul_filter_rule[i].filter_hdl; } if (qmi_filter_notify_send(&req)) { IPAWANDBG("add filter rule index on A7-RX failed\n"); Loading Loading @@ -631,9 +638,9 @@ static int wwan_del_ul_flt_rule_to_ipa(void) param->num_hdls = (uint8_t) 1; for (i = 0; i < old_num_q6_rule; i++) { param->ip = q6_ul_filter_rule[i].ip; param->ip = ipa_qmi_ctx->q6_ul_filter_rule[i].ip; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del)); flt_rule_entry.hdl = q6_ul_filter_rule_hdl[i]; flt_rule_entry.hdl = ipa_qmi_ctx->q6_ul_filter_rule_hdl[i]; /* debug rt-hdl*/ IPAWANDBG("delete-IPA rule index(%d)\n", i); memcpy(&(param->hdl[0]), &flt_rule_entry, Loading Loading @@ -738,7 +745,7 @@ static int wwan_register_to_ipa(int index) ext_properties.num_props = num_q6_rule; for (i = 0; i < num_q6_rule; i++) { memcpy(&(ext_properties.prop[i]), &(q6_ul_filter_rule[i]), &(ipa_qmi_ctx->q6_ul_filter_rule[i]), sizeof(struct ipa_ioc_ext_intf_prop)); ext_properties.prop[i].mux_id = mux_channel[index].mux_id; IPAWANDBG("index %d ip: %d rt-tbl:%d\n", i, Loading Loading @@ -1709,7 +1716,6 @@ static int ipa_wwan_probe(struct platform_device *pdev) memset(&ipa_to_apps_ep_cfg, 0, sizeof(struct ipa_sys_connect_params)); /* initialize ex property setup */ memset(q6_ul_filter_rule, 0, sizeof(q6_ul_filter_rule)); num_q6_rule = 0; old_num_q6_rule = 0; rmnet_index = 0; Loading Loading
drivers/platform/msm/ipa/ipa_qmi_service.c +28 −1 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ static bool qmi_modem_init_fin, qmi_indication_fin; static struct work_struct ipa_qmi_service_init_work; static bool is_load_uc; static uint32_t ipa_wan_platform; struct ipa_qmi_context *ipa_qmi_ctx; /* QMI A5 service */ Loading Loading @@ -453,6 +453,13 @@ int qmi_filter_request_send(struct ipa_install_fltr_rule_req_msg_v01 *req) req->filter_spec_list_len); } /* cache the qmi_filter_request */ memcpy(&(ipa_qmi_ctx->ipa_install_fltr_rule_req_msg_cache[ ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg]), req, sizeof(struct ipa_install_fltr_rule_req_msg_v01)); ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg++; ipa_qmi_ctx->num_ipa_install_fltr_rule_req_msg %= 10; req_desc.max_msg_len = QMI_IPA_INSTALL_FILTER_RULE_REQ_MAX_MSG_LEN_V01; req_desc.msg_id = QMI_IPA_INSTALL_FILTER_RULE_REQ_V01; req_desc.ei_array = ipa_install_fltr_rule_req_msg_data_v01_ei; Loading Loading @@ -498,6 +505,14 @@ int qmi_filter_notify_send(struct ipa_fltr_installed_notif_req_msg_v01 *req) req->filter_index_list[i].filter_index); return -EINVAL; } /* cache the qmi_filter_request */ memcpy(&(ipa_qmi_ctx->ipa_fltr_installed_notif_req_msg_cache[ ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg]), req, sizeof(struct ipa_fltr_installed_notif_req_msg_v01)); ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg++; ipa_qmi_ctx->num_ipa_fltr_installed_notif_req_msg %= 10; req_desc.max_msg_len = QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_MAX_MSG_LEN_V01; req_desc.msg_id = QMI_IPA_FILTER_INSTALLED_NOTIF_REQ_V01; Loading Loading @@ -650,6 +665,13 @@ static void ipa_qmi_service_init_worker(struct work_struct *work) /* Initialize QMI-service*/ IPAWANDBG("IPA A7 QMI init OK :>>>>\n"); /* start the QMI msg cache */ ipa_qmi_ctx = kzalloc(sizeof(*ipa_qmi_ctx), GFP_KERNEL); if (!ipa_qmi_ctx) { IPAWANERR(":kzalloc err.\n"); return; } ipa_svc_workqueue = create_singlethread_workqueue("ipa_A7_svc"); if (!ipa_svc_workqueue) { IPAWANERR("Creating ipa_A7_svc workqueue failed\n"); Loading Loading @@ -780,6 +802,11 @@ void ipa_qmi_service_exit(void) ipa_clnt_resp_workqueue = NULL; } /* clean the QMI msg cache */ if (ipa_qmi_ctx != NULL) { kfree(ipa_qmi_ctx); ipa_qmi_ctx = NULL; } ipa_svc_handle = 0; qmi_modem_init_fin = false; qmi_indication_fin = false; Loading
drivers/platform/msm/ipa/ipa_qmi_service.h +15 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-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 Loading @@ -25,6 +25,7 @@ #define IPA_A7_QMAP_HDR_NAME "ipa_qmap_hdr" #define IPA_DFLT_WAN_RT_TBL_NAME "ipa_dflt_wan_rt" #define MAX_NUM_Q6_RULE 35 #define MAX_NUM_QMI_RULE_CACHE 10 #define DEV_NAME "ipa-wan" #define SUBSYS_MODEM "modem" Loading @@ -33,6 +34,19 @@ #define IPAWANERR(fmt, args...) \ pr_err(DEV_NAME " %s:%d " fmt, __func__, __LINE__, ## args) extern struct ipa_qmi_context *ipa_qmi_ctx; struct ipa_qmi_context { struct ipa_ioc_ext_intf_prop q6_ul_filter_rule[MAX_NUM_Q6_RULE]; u32 q6_ul_filter_rule_hdl[MAX_NUM_Q6_RULE]; int num_ipa_install_fltr_rule_req_msg; struct ipa_install_fltr_rule_req_msg_v01 ipa_install_fltr_rule_req_msg_cache[MAX_NUM_QMI_RULE_CACHE]; int num_ipa_fltr_installed_notif_req_msg; struct ipa_fltr_installed_notif_req_msg_v01 ipa_fltr_installed_notif_req_msg_cache[MAX_NUM_QMI_RULE_CACHE]; }; struct rmnet_mux_val { uint32_t mux_id; int8_t vchannel_name[IFNAMSIZ]; Loading
drivers/platform/msm/ipa/rmnet_ipa.c +118 −112 Original line number Diff line number Diff line Loading @@ -48,8 +48,6 @@ static struct net_device *ipa_netdevs[IPA_WWAN_DEVICE_COUNT]; static struct ipa_sys_connect_params apps_to_ipa_ep_cfg, ipa_to_apps_ep_cfg; static u32 qmap_hdr_hdl, dflt_v4_wan_rt_hdl, dflt_v6_wan_rt_hdl; static struct ipa_ioc_ext_intf_prop q6_ul_filter_rule[MAX_NUM_Q6_RULE]; static u32 q6_ul_filter_rule_hdl[MAX_NUM_Q6_RULE]; static struct rmnet_mux_val mux_channel[MAX_NUM_OF_MUX_CHANNEL]; static int num_q6_rule, old_num_q6_rule; static int rmnet_index; Loading Loading @@ -395,143 +393,150 @@ int copy_ul_filter_rule_to_ipa(struct ipa_install_fltr_rule_req_msg_v01 break; } /* construct UL_filter_rule handler QMI use-cas */ q6_ul_filter_rule[i].filter_hdl = ipa_qmi_ctx->q6_ul_filter_rule[i].filter_hdl = UL_FILTER_RULE_HANDLE_START + i; rule_hdl[i] = q6_ul_filter_rule[i].filter_hdl; q6_ul_filter_rule[i].ip = rule_req->filter_spec_list[i].ip_type; q6_ul_filter_rule[i].action = rule_hdl[i] = ipa_qmi_ctx->q6_ul_filter_rule[i].filter_hdl; ipa_qmi_ctx->q6_ul_filter_rule[i].ip = rule_req->filter_spec_list[i].ip_type; ipa_qmi_ctx->q6_ul_filter_rule[i].action = rule_req->filter_spec_list[i].filter_action; if (rule_req->filter_spec_list[i].is_routing_table_index_valid == true) q6_ul_filter_rule[i].rt_tbl_idx = ipa_qmi_ctx->q6_ul_filter_rule[i].rt_tbl_idx = rule_req->filter_spec_list[i].route_table_index; if (rule_req->filter_spec_list[i].is_mux_id_valid == true) q6_ul_filter_rule[i].mux_id = ipa_qmi_ctx->q6_ul_filter_rule[i].mux_id = rule_req->filter_spec_list[i].mux_id; q6_ul_filter_rule[i].eq_attrib.rule_eq_bitmap = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.rule_eq_bitmap = rule_req->filter_spec_list[i].filter_rule. rule_eq_bitmap; q6_ul_filter_rule[i].eq_attrib.tos_eq_present = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tos_eq_present = rule_req->filter_spec_list[i].filter_rule. tos_eq_present; q6_ul_filter_rule[i].eq_attrib.tos_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tos_eq = rule_req->filter_spec_list[i].filter_rule.tos_eq; q6_ul_filter_rule[i].eq_attrib.protocol_eq_present = rule_req->filter_spec_list[i].filter_rule. protocol_eq_present; q6_ul_filter_rule[i].eq_attrib.protocol_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. protocol_eq_present = rule_req->filter_spec_list[i]. filter_rule.protocol_eq_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.protocol_eq = rule_req->filter_spec_list[i].filter_rule. protocol_eq; q6_ul_filter_rule[i].eq_attrib.num_ihl_offset_range_16 = rule_req->filter_spec_list[i].filter_rule. num_ihl_offset_range_16; for (j = 0; j < q6_ul_filter_rule[i].eq_attrib. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_ihl_offset_range_16 = rule_req->filter_spec_list[i]. filter_rule.num_ihl_offset_range_16; for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_ihl_offset_range_16; j++) { q6_ul_filter_rule[i].eq_attrib.ihl_offset_range_16[j]. offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_range_16[j].offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_range_16[j]. range_low = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_range_16[j].range_low; q6_ul_filter_rule[i].eq_attrib.ihl_offset_range_16[j]. range_high = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_range_16[j].range_high; } q6_ul_filter_rule[i].eq_attrib.num_offset_meq_32 = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_range_16[j].offset = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_range_16[j].offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_range_16[j].range_low = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_range_16[j].range_low; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_range_16[j].range_high = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_range_16[j].range_high; } ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.num_offset_meq_32 = rule_req->filter_spec_list[i].filter_rule. num_offset_meq_32; for (j = 0; j < q6_ul_filter_rule[i].eq_attrib. for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_offset_meq_32; j++) { q6_ul_filter_rule[i].eq_attrib.offset_meq_32[j].offset = rule_req->filter_spec_list[i].filter_rule. offset_meq_32[j].offset; q6_ul_filter_rule[i].eq_attrib.offset_meq_32[j].mask = rule_req->filter_spec_list[i].filter_rule. offset_meq_32[j].mask; q6_ul_filter_rule[i].eq_attrib.offset_meq_32[j].value = rule_req->filter_spec_list[i].filter_rule. offset_meq_32[j].value; } q6_ul_filter_rule[i].eq_attrib.tc_eq_present = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_32[j].offset = rule_req->filter_spec_list[i]. filter_rule.offset_meq_32[j].offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_32[j].mask = rule_req->filter_spec_list[i]. filter_rule.offset_meq_32[j].mask; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_32[j].value = rule_req->filter_spec_list[i]. filter_rule.offset_meq_32[j].value; } ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tc_eq_present = rule_req->filter_spec_list[i].filter_rule.tc_eq_present; q6_ul_filter_rule[i].eq_attrib.tc_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.tc_eq = rule_req->filter_spec_list[i].filter_rule.tc_eq; q6_ul_filter_rule[i].eq_attrib.fl_eq_present = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.fl_eq_present = rule_req->filter_spec_list[i].filter_rule. flow_eq_present; q6_ul_filter_rule[i].eq_attrib.fl_eq = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.fl_eq = rule_req->filter_spec_list[i].filter_rule.flow_eq; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_16_present = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_16_present; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_16.offset = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_16.offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_16.value = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_16.value; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_32_present = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_32_present; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_32.offset = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_32.offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_eq_32.value = rule_req->filter_spec_list[i].filter_rule. ihl_offset_eq_32.value; q6_ul_filter_rule[i].eq_attrib.num_ihl_offset_meq_32 = rule_req->filter_spec_list[i].filter_rule. num_ihl_offset_meq_32; for (j = 0; j < q6_ul_filter_rule[i]. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_16_present = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_16_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_16.offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_16.offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_16.value = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_16.value; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_32_present = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_32_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_32.offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_32.offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_eq_32.value = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_eq_32.value; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_ihl_offset_meq_32 = rule_req->filter_spec_list[i]. filter_rule.num_ihl_offset_meq_32; for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i]. eq_attrib.num_ihl_offset_meq_32; j++) { q6_ul_filter_rule[i].eq_attrib.ihl_offset_meq_32[j]. offset = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_meq_32[j].offset; q6_ul_filter_rule[i].eq_attrib.ihl_offset_meq_32[j]. mask = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_meq_32[j].mask; q6_ul_filter_rule[i].eq_attrib.ihl_offset_meq_32[j]. value = rule_req->filter_spec_list[i]. filter_rule.ihl_offset_meq_32[j].value; } q6_ul_filter_rule[i].eq_attrib.num_offset_meq_128 = ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_meq_32[j].offset = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_meq_32[j].offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_meq_32[j].mask = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_meq_32[j].mask; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ihl_offset_meq_32[j].value = rule_req-> filter_spec_list[i].filter_rule. ihl_offset_meq_32[j].value; } ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.num_offset_meq_128 = rule_req->filter_spec_list[i].filter_rule. num_offset_meq_128; for (j = 0; j < q6_ul_filter_rule[i].eq_attrib. for (j = 0; j < ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. num_offset_meq_128; j++) { q6_ul_filter_rule[i].eq_attrib.offset_meq_128[j]. offset = rule_req->filter_spec_list[i]. filter_rule.offset_meq_128[j].offset; memcpy(q6_ul_filter_rule[i].eq_attrib. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_128[j].offset = rule_req-> filter_spec_list[i].filter_rule. offset_meq_128[j].offset; memcpy(ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_128[j].mask, rule_req->filter_spec_list[i]. filter_rule.offset_meq_128[j].mask, 16); memcpy(q6_ul_filter_rule[i].eq_attrib.offset_meq_128[j]. value, rule_req->filter_spec_list[i]. filter_rule.offset_meq_128[j].value, 16); filter_rule.offset_meq_128[j].mask, 16); memcpy(ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. offset_meq_128[j].value, rule_req-> filter_spec_list[i].filter_rule. offset_meq_128[j].value, 16); } q6_ul_filter_rule[i].eq_attrib.metadata_meq32_present = rule_req->filter_spec_list[i]. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. metadata_meq32_present = rule_req->filter_spec_list[i]. filter_rule.metadata_meq32_present; q6_ul_filter_rule[i].eq_attrib.metadata_meq32.offset = rule_req->filter_spec_list[i].filter_rule. metadata_meq32.offset; q6_ul_filter_rule[i].eq_attrib.metadata_meq32.mask = rule_req->filter_spec_list[i].filter_rule. metadata_meq32.mask; q6_ul_filter_rule[i].eq_attrib.metadata_meq32.value = rule_req->filter_spec_list[i].filter_rule. ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. metadata_meq32.offset = rule_req->filter_spec_list[i]. filter_rule.metadata_meq32.offset; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. metadata_meq32.mask = rule_req->filter_spec_list[i]. filter_rule.metadata_meq32.mask; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib.metadata_meq32. value = rule_req->filter_spec_list[i].filter_rule. metadata_meq32.value; q6_ul_filter_rule[i].eq_attrib.ipv4_frag_eq_present = rule_req->filter_spec_list[i].filter_rule. ipv4_frag_eq_present; ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib. ipv4_frag_eq_present = rule_req->filter_spec_list[i]. filter_rule.ipv4_frag_eq_present; } return rc; } Loading @@ -557,12 +562,13 @@ static int wwan_add_ul_flt_rule_to_ipa(void) param->num_rules = (uint8_t)1; for (i = 0; i < num_q6_rule; i++) { param->ip = q6_ul_filter_rule[i].ip; param->ip = ipa_qmi_ctx->q6_ul_filter_rule[i].ip; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add)); flt_rule_entry.at_rear = true; flt_rule_entry.rule.action = q6_ul_filter_rule[i].action; flt_rule_entry.rule.action = ipa_qmi_ctx->q6_ul_filter_rule[i].action; flt_rule_entry.rule.rt_tbl_idx = q6_ul_filter_rule[i].rt_tbl_idx; = ipa_qmi_ctx->q6_ul_filter_rule[i].rt_tbl_idx; flt_rule_entry.rule.retain_hdr = true; /* debug rt-hdl*/ Loading @@ -570,7 +576,7 @@ static int wwan_add_ul_flt_rule_to_ipa(void) i, flt_rule_entry.rule.rt_tbl_idx); flt_rule_entry.rule.eq_attrib_type = true; memcpy(&(flt_rule_entry.rule.eq_attrib), &q6_ul_filter_rule[i].eq_attrib, &ipa_qmi_ctx->q6_ul_filter_rule[i].eq_attrib, sizeof(struct ipa_ipfltri_rule_eq)); memcpy(&(param->rules[0]), &flt_rule_entry, sizeof(struct ipa_flt_rule_add)); Loading @@ -579,7 +585,8 @@ static int wwan_add_ul_flt_rule_to_ipa(void) IPAWANERR("add A7 UL filter rule(%d) failed\n", i); } else { /* store the rule handler */ q6_ul_filter_rule_hdl[i] = param->rules[0].flt_rule_hdl; ipa_qmi_ctx->q6_ul_filter_rule_hdl[i] = param->rules[0].flt_rule_hdl; } } Loading @@ -590,7 +597,7 @@ static int wwan_add_ul_flt_rule_to_ipa(void) req.install_status = QMI_RESULT_SUCCESS_V01; req.filter_index_list_len = num_q6_rule; for (i = 0; i < num_q6_rule; i++) { if (q6_ul_filter_rule[i].ip == IPA_IP_v4) { if (ipa_qmi_ctx->q6_ul_filter_rule[i].ip == IPA_IP_v4) { req.filter_index_list[i].filter_index = num_v4_rule; num_v4_rule++; } else { Loading @@ -598,7 +605,7 @@ static int wwan_add_ul_flt_rule_to_ipa(void) num_v6_rule++; } req.filter_index_list[i].filter_handle = q6_ul_filter_rule[i].filter_hdl; ipa_qmi_ctx->q6_ul_filter_rule[i].filter_hdl; } if (qmi_filter_notify_send(&req)) { IPAWANDBG("add filter rule index on A7-RX failed\n"); Loading Loading @@ -631,9 +638,9 @@ static int wwan_del_ul_flt_rule_to_ipa(void) param->num_hdls = (uint8_t) 1; for (i = 0; i < old_num_q6_rule; i++) { param->ip = q6_ul_filter_rule[i].ip; param->ip = ipa_qmi_ctx->q6_ul_filter_rule[i].ip; memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_del)); flt_rule_entry.hdl = q6_ul_filter_rule_hdl[i]; flt_rule_entry.hdl = ipa_qmi_ctx->q6_ul_filter_rule_hdl[i]; /* debug rt-hdl*/ IPAWANDBG("delete-IPA rule index(%d)\n", i); memcpy(&(param->hdl[0]), &flt_rule_entry, Loading Loading @@ -738,7 +745,7 @@ static int wwan_register_to_ipa(int index) ext_properties.num_props = num_q6_rule; for (i = 0; i < num_q6_rule; i++) { memcpy(&(ext_properties.prop[i]), &(q6_ul_filter_rule[i]), &(ipa_qmi_ctx->q6_ul_filter_rule[i]), sizeof(struct ipa_ioc_ext_intf_prop)); ext_properties.prop[i].mux_id = mux_channel[index].mux_id; IPAWANDBG("index %d ip: %d rt-tbl:%d\n", i, Loading Loading @@ -1709,7 +1716,6 @@ static int ipa_wwan_probe(struct platform_device *pdev) memset(&ipa_to_apps_ep_cfg, 0, sizeof(struct ipa_sys_connect_params)); /* initialize ex property setup */ memset(q6_ul_filter_rule, 0, sizeof(q6_ul_filter_rule)); num_q6_rule = 0; old_num_q6_rule = 0; rmnet_index = 0; Loading